Subversion Repositories HomeAutomation

Rev

Rev 981 | Rev 984 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 981 Rev 983
Line 16... Line 16...
16
 *   You should have received a copy of the GNU General Public License     *
16
 *   You should have received a copy of the GNU General Public License     *
17
 *   along with this program; if not, write to the                         *
17
 *   along with this program; if not, write to the                         *
18
 *   Free Software Foundation, Inc.,                                       *
18
 *   Free Software Foundation, Inc.,                                       *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20
 ***************************************************************************/
20
 ***************************************************************************/
21
 
-
 
22
#include <map>
-
 
23
 
-
 
24
 
-
 
25
#include <vector>
-
 
26
 
-
 
27
 
21
 
28
#include "asyncsocket.h"
22
#include "asyncsocket.h"
29
 
23
 
30
map<string, AsyncSocket*> AsyncSocket::mySockets;
-
 
31
Mutex AsyncSocket::mySocketsMutex;
24
int socketCount = 1;
32
 
25
 
33
AsyncSocket::AsyncSocket()
26
AsyncSocket::AsyncSocket()
34
{
27
{
35
    myId = itos(time(NULL)) + itos(mySockets.size());
-
 
36
 
-
 
37
    mySockets[myId] = this;
28
    myId = socketCount++;
38
 
-
 
39
    cout << "DEBUG: Started " << myId << endl;
-
 
40
 
-
 
41
    mySocket = -1;
29
    mySocket = -1;
42
    myReconnectTimeout = 0;
30
    myReconnectTimeout = 0;
43
    myForceReconnect = false;
31
    myForceReconnect = false;
44
 
-
 
45
 
32
 
46
    Thread<AsyncSocket>();
33
    Thread<AsyncSocket>();
47
}
34
}
48
 
35
 
49
AsyncSocket::~AsyncSocket()
36
AsyncSocket::~AsyncSocket()
50
{
37
{
51
    mySemaphore.unlock();
-
 
52
 
-
 
53
    if (mySocket != -1)
38
    if (mySocket != -1)
54
    {
39
    {
55
        ::close(mySocket);
40
        ::close(mySocket);
56
        mySocket = -1;
-
 
57
    }
41
    }
58
 
-
 
59
    mySockets.erase(myId);
-
 
60
 
42
 
61
    stop();
43
    stop();
62
}
44
}
63
 
45
 
64
void AsyncSocket::run()
46
void AsyncSocket::run()
65
{
47
{
66
    SyslogStream &slog = SyslogStream::getInstance();
48
    SyslogStream &slog = SyslogStream::getInstance();
67
 
49
 
68
    if (!isConnected())
50
    if (!isConnected())
69
    {
51
    {
70
        if (myReconnectTimeout == 0)
52
        if (myReconnectTimeout == 0)
71
        {
53
        {
72
            connect();
54
            connect();
73
        }
55
        }
74
        else
56
        else
75
        {
57
        {
76
            reconnectLoop();
58
            reconnectLoop();
77
        }
59
        }
78
    }
60
    }
79
 
61
 
80
    char buf[MAXBUFFER + 1];
62
    char buf[MAXBUFFER + 1];
81
    string data;
63
    string data;
82
    int status;
64
    int status;
83
    int rc;
-
 
84
    int timeSince = time(NULL) + 10;
-
 
85
 
65
 
-
 
66
    bool loop = true;
86
    try
67
    try
87
    {
68
    {
88
        while (1)
69
        while (loop)
89
        {
70
        {
90
            AsyncSocket::mySemaphore.lock();
-
 
91
 
-
 
92
            rc = mySemaphore.wait(10);
-
 
93
 
-
 
94
            AsyncSocket::mySemaphore.unlock();
-
 
95
 
-
 
96
            if (myForceReconnect)
71
            if (myForceReconnect)
97
            {
72
            {
98
                slog << "Disconnected from server.\n";
-
 
99
                reconnectLoop();
73
                reconnectLoop();
100
                timeSince = time(NULL) + 10;
-
 
101
                continue;
-
 
102
            }
74
            }
103
 
75
 
104
            //cout << "Socket awoken...\n";
-
 
105
           
-
 
106
            if (rc == ETIMEDOUT)
-
 
107
            {
-
 
108
                /* Socket timed out, this means we have not received anything in some time
-
 
109
                and we should check the connection */
-
 
110
 
-
 
111
                setEvent(ASYNCSOCKET_EVENT_INACTIVITY);
-
 
112
                timeSince = time(NULL);
-
 
113
            }
-
 
114
            else
-
 
115
            {
-
 
116
                while (myOutQueue.size() > 0)
-
 
117
                {
-
 
118
                    data = myOutQueue.pop();
-
 
119
 
-
 
120
                    sendDataDirect(data);
-
 
121
                }
-
 
122
 
-
 
123
                memset(buf, 0, MAXBUFFER + 1);
76
            memset(buf, 0, MAXBUFFER + 1);
124
 
-
 
125
                status = ::recv(mySocket, buf, MAXBUFFER, 0);
77
            status = ::recv(mySocket, buf, MAXBUFFER, 0);
126
 
78
 
127
                if (status == -1)
79
            if (status == -1)
128
                {
80
            {
129
                    switch (errno)
81
                switch (errno)
130
                    {
82
                {
131
                        case EAGAIN:
83
                    case EAGAIN:
132
                        //slog << "The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n";
84
                    throw new SocketException("The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.");
133
                        break;
85
                    break;
134
 
86
 
135
                        case EBADF:
87
                    case EBADF:
136
                        throw new SocketException("The argument s is an invalid descriptor.");
88
                    throw new SocketException("The argument s is an invalid descriptor.");
137
 
89
 
Line 143... Line 95...
143
 
95
 
144
                        case EINTR:
96
                    case EINTR:
145
                        throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7).");
97
                    throw new SocketException("The receive was interrupted by delivery of a signal before any data were available; see signal(7).");
146
 
98
 
147
                        case EINVAL:
99
                    case EINVAL:
148
                        //throw new SocketException("2Invalid argument passed.");
100
                    throw new SocketException("Invalid argument passed.");
149
                        slog << "Disconnected from server.\n";
-
 
150
                        reconnectLoop();
-
 
151
                        timeSince = time(NULL) + 10;
-
 
152
                        break;
101
                    break;
153
 
102
 
154
                        case ENOMEM:
103
                    case ENOMEM:
155
                        throw new SocketException("Could not allocate memory for recvmsg().");
104
                    throw new SocketException("Could not allocate memory for recvmsg().");
156
 
105
 
157
                        case ENOTCONN:
106
                    case ENOTCONN:
158
                        throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and  accept(2)).");
107
                    throw new SocketException("The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and  accept(2)).");
159
 
108
 
160
                        case ENOTSOCK:
109
                    case ENOTSOCK:
161
                        throw new SocketException("The argument s does not refer to a socket.");
110
                    throw new SocketException("The argument s does not refer to a socket.");
-
 
111
 
-
 
112
                    case ECONNRESET:
-
 
113
                    setEvent(ASYNCSOCKET_EVENT_RESET);
-
 
114
                    if (myReconnectTimeout > 0)
-
 
115
                    {
-
 
116
                        reconnectLoop();
-
 
117
                    }
-
 
118
                    else
-
 
119
                    {
-
 
120
                        loop = false;
-
 
121
                    }
-
 
122
                    break;
162
 
123
 
163
                        default:
124
                    default:
164
                        slog << "Unknow exception: " + itos(errno) + "\n";
125
                    throw new SocketException("Unknow exception: " + itos(errno));
165
                        break;
126
                    break;
166
                    }
127
                }
167
                }
128
            }
168
                else if (status == 0)
129
            else if (status == 0)
169
                {
130
            {
-
 
131
                setEvent(ASYNCSOCKET_EVENT_CLOSED);
170
                    slog << "Disconnected from server.\n";
132
                if (myReconnectTimeout > 0)
-
 
133
                {
171
                    reconnectLoop();
134
                    reconnectLoop();
-
 
135
                }
-
 
136
                else
-
 
137
                {
172
                    timeSince = time(NULL);
138
                    loop = false;
-
 
139
                }
173
                }
140
            }
174
                else if (status > 0)
141
            else if (status > 0)
175
                {
142
            {
176
                    timeSince = time(NULL) + 10;
-
 
177
 
-
 
178
                    data = buf;
143
                data = buf;
179
 
144
 
180
                    //slog << "Receiving: " + data + "\n";
145
                //slog << "Received: " + data + "\n";
181
 
146
 
182
                    myInQueue.push(data);
147
                myInQueue.push(data);
183
 
-
 
184
                    setEvent(ASYNCSOCKET_EVENT_DATA);
148
                setEvent(ASYNCSOCKET_EVENT_DATA);
185
                }
-
 
186
               
-
 
187
                if (timeSince + 10 < time(NULL))
-
 
188
                {
-
 
189
                    setEvent(ASYNCSOCKET_EVENT_INACTIVITY);
-
 
190
                    timeSince = time(NULL);
-
 
191
                }
-
 
192
            }
149
            }
193
        }
150
        }
194
    }
151
    }
195
    catch (SocketException *e)
152
    catch (SocketException *e)
196
    {
153
    {
197
        slog << "Exception: " + e->getDescription() + "\n";
154
        slog << "Exception: " + e->getDescription() + "\n";
198
        //mySemaphore.unlock();
-
 
199
        setEvent(ASYNCSOCKET_EVENT_DIED);
155
        setEvent(ASYNCSOCKET_EVENT_DIED);
200
        stop();
-
 
201
    }
156
    }
202
 
157
 
203
    close();
158
    close();
204
 
-
 
205
    //mySemaphore.unlock();
-
 
206
}
159
}
207
 
160
 
208
void AsyncSocket::reconnectLoop()
161
void AsyncSocket::reconnectLoop()
209
{
162
{
210
    if (myReconnectTimeout == 0)
-
 
211
    {
-
 
212
        close();
-
 
213
        throw new SocketException("Connection is closed.");
-
 
214
    }
-
 
215
 
-
 
216
    SyslogStream &slog = SyslogStream::getInstance();
163
    SyslogStream &slog = SyslogStream::getInstance();
217
 
164
 
218
    while (1)
165
    while (1)
219
    {
166
    {
220
        try
167
        try
Line 222... Line 169...
222
            connect();
169
            connect();
223
            break;
170
            break;
224
        }
171
        }
225
        catch (SocketException *e)
172
        catch (SocketException *e)
226
        {
173
        {
-
 
174
            setEvent(ASYNCSOCKET_EVENT_CONNECT_FAILED);
-
 
175
            setEvent(ASYNCSOCKET_EVENT_WAITING_TO_RECONNECT);
227
            slog << "Could not connect: " + e->getDescription() + "\n";
176
            slog << "Could not connect: " + e->getDescription() + "\n";//FIXME: Remove these
228
            slog << "Will try again in " + itos(myReconnectTimeout) + " seconds\n";
177
            slog << "Will try again in " + itos(myReconnectTimeout) + " seconds\n";
229
            sleep(myReconnectTimeout);
178
            sleep(myReconnectTimeout);
230
        }
179
        }
231
    }
180
    }
232
}
181
}
Line 355... Line 304...
355
void AsyncSocket::connect()
304
void AsyncSocket::connect()
356
{
305
{
357
    SyslogStream &slog = SyslogStream::getInstance();
306
    SyslogStream &slog = SyslogStream::getInstance();
358
 
307
 
359
    create();
308
    create();
360
 
-
 
361
    int on = 1;
-
 
362
    ///FIXME: Verify that this works
-
 
363
    int status = setsockopt(mySocket, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on));
-
 
364
    if (status == -1)
-
 
365
    {
-
 
366
        close();
-
 
367
        throw new SocketException("Connect:Keepalive: " + itos(errno));
-
 
368
    }
-
 
369
 
-
 
370
    ///FIXME: Verify that this works
-
 
371
    status = setsockopt(mySocket, SOL_TCP, TCP_KEEPIDLE, (const char*)&on, sizeof(on));
-
 
372
    if (status == -1)
-
 
373
    {
-
 
374
        close();
-
 
375
        throw new SocketException("Connect:Keepidle: " + itos(errno));
-
 
376
    }
-
 
377
 
309
 
378
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
310
    memset(&myAddressStruct, 0, sizeof(myAddressStruct));
379
 
311
 
380
    myAddressStruct.sin_family = AF_INET;
312
    myAddressStruct.sin_family = AF_INET;
381
    myAddressStruct.sin_port = htons(myPort);
313
    myAddressStruct.sin_port = htons(myPort);
-
 
314
 
-
 
315
    //slog << "Trying to resolv " + myAddress + "\n";
382
 
316
 
383
    struct hostent *hptr = gethostbyname(myAddress.c_str());
317
    struct hostent *hptr = gethostbyname(myAddress.c_str());
384
    if (hptr == NULL)
318
    if (hptr == NULL)
385
    {
319
    {
386
        close();
320
        close();
387
        throw new SocketException("Connect: Could not resolv ip address");
321
        throw new SocketException("Connect: Could not resolv ip address");
388
    }
322
    }
389
 
323
 
-
 
324
   
390
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
325
    memcpy(&myAddressStruct.sin_addr, hptr->h_addr, hptr->h_length);
391
    /*
-
 
392
    status = inet_pton(AF_INET, myAddress.c_str(), &myAddressStruct.sin_addr);
-
 
393
 
326
 
394
    if (status == -1)
-
 
395
    {
-
 
396
        if (errno == EAFNOSUPPORT)
-
 
397
            throw new SocketException("Connect: EAFNOSUPPORT");
-
 
398
    }
-
 
399
    */
-
 
400
 
-
 
401
    slog << "Trying to connect...\n";
-
 
402
 
-
 
403
    status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
327
    int status = ::connect(mySocket, (sockaddr*)&myAddressStruct, sizeof(myAddressStruct));
404
 
328
 
405
    if (status == -1)
329
    if (status == -1)
406
    {
330
    {
407
        close();
331
        close();
408
        switch (errno)
332
        switch (errno)
409
        {
333
        {
410
            case EACCES:
334
            case EACCES:
411
            throw new SocketException("For Unix domain sockets, which are identified by pathname: Write permission is denied on the socket file, or search per- mission is denied for one of the directories in the path prefix.  (See also path_resolution(7).)");
335
            throw new SocketException("For Unix domain sockets, which are identified by pathname: Write permission is denied on the socket file, or search per- mission is denied for one of the directories in the path prefix.  (See also path_resolution(7).)");
412
 
336
 
413
            case EPERM:
337
            case EPERM:
414
            throw new SocketException("The user tried to connect to a broadcast address without having the socket broadcast  flag  enabled  or  the  connection request failed because of a local firewall rule.");
338
            throw new SocketException("The user tried to connect to a broadcast address without having the socket broadcast  flag  enabled  or  the  connection request failed because of a local firewall rule.");
415
 
339
 
416
            case EADDRINUSE:
340
            case EADDRINUSE:
417
            throw new SocketException("Local address is already in use.");
341
            throw new SocketException("Local address is already in use.");
418
 
342
 
419
            case EAFNOSUPPORT:
343
            case EAFNOSUPPORT:
420
            throw new SocketException("The passed address didn't have the correct address family in its sa_family field.");
344
            throw new SocketException("The passed address didn't have the correct address family in its sa_family field.");
421
 
345
 
422
            case EAGAIN:
346
            case EAGAIN:
423
            throw new SocketException("No more free local ports or insufficient entries in the routing cache.  For AF_INET see the net.ipv4.ip_local_port_range sysctl in ip(7) on how to increase the number of local ports.");
347
            throw new SocketException("No more free local ports or insufficient entries in the routing cache.  For AF_INET see the net.ipv4.ip_local_port_range sysctl in ip(7) on how to increase the number of local ports.");
424
 
348
 
425
            case EALREADY:
349
            case EALREADY:
426
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
350
            throw new SocketException("The socket is non-blocking and a previous connection attempt has not yet been completed.");
427
 
351
 
428
            case EBADF:
352
            case EBADF:
429
            throw new SocketException("The file descriptor is not a valid index in the descriptor table.");
353
            throw new SocketException("The file descriptor is not a valid index in the descriptor table.");
430
 
354
 
431
            case ECONNREFUSED:
355
            case ECONNREFUSED:
432
            throw new SocketException("No-one listening on the remote address.");
356
            throw new SocketException("No-one listening on the remote address.");
433
 
357
 
434
            case EFAULT:
358
            case EFAULT:
435
            throw new SocketException("The socket structure address is outside the user's address space.");
359
            throw new SocketException("The socket structure address is outside the user's address space.");
436
 
360
 
437
            case EINPROGRESS:
361
            case EINPROGRESS:
438
            throw new SocketException("The socket is non-blocking and the connection cannot be completed immediately.  It is possible to select(2)  or  poll(2) for  completion  by  selecting the socket for writing.  After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed  successfully  (SO_ERROR  is  zero)  or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure).");
362
            throw new SocketException("The socket is non-blocking and the connection cannot be completed immediately.  It is possible to select(2)  or  poll(2) for  completion  by  selecting the socket for writing.  After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed  successfully  (SO_ERROR  is  zero)  or unsuccessfully (SO_ERROR is one of the usual error codes listed here, explaining the reason for the failure).");
439
 
363
 
440
            case EINTR:
364
            case EINTR:
441
            throw new SocketException("The system call was interrupted by a signal that was caught; see signal(7).");
365
            throw new SocketException("The system call was interrupted by a signal that was caught; see signal(7).");
Line 452... Line 376...
452
            case ETIMEDOUT:
376
            case ETIMEDOUT:
453
            throw new SocketException("Timeout  while  attempting  connection.  The server may be too busy to accept new connections.  Note that for IP sockets the timeout may be very long when syncookies are enabled on the server.");
377
            throw new SocketException("Timeout  while  attempting  connection.  The server may be too busy to accept new connections.  Note that for IP sockets the timeout may be very long when syncookies are enabled on the server.");
454
 
378
 
455
            default:
379
            default:
456
            throw new SocketException("Other errors may be generated by the underlying protocol modules. : " + itos(errno));
380
            throw new SocketException("Other errors may be generated by the underlying protocol modules. : " + itos(errno));
457
        }
381
        }
458
    }
-
 
459
 
-
 
460
    struct sigaction saio;
-
 
461
    saio.sa_handler = AsyncSocket::signalHandler;
-
 
462
    sigemptyset(&saio.sa_mask);
-
 
463
    saio.sa_flags = 0;
-
 
464
    saio.sa_restorer = NULL;
-
 
465
    sigaction(SIGIO, &saio, NULL);
-
 
466
 
-
 
467
    fcntl(mySocket, F_SETOWN, getpid());
-
 
468
    int flags = fcntl(mySocket, F_GETFL);
-
 
469
 
-
 
470
    if (flags < 0)
-
 
471
    {
-
 
472
        close();
-
 
473
        throw new SocketException("Async socket fcntl failed");
-
 
474
    }
382
    }
475
 
-
 
476
    fcntl(mySocket, F_SETFL, flags | O_NONBLOCK | FASYNC);
-
 
477
 
383
 
478
    myForceReconnect = false;
384
    myForceReconnect = false;
479
 
385
 
480
    slog << "Connection established.\n";
386
    setEvent(ASYNCSOCKET_EVENT_CONNECTED);
481
}
387
}
482
 
388
 
483
void AsyncSocket::close()
389
void AsyncSocket::close()
484
{
390
{
485
    if (mySocket != -1)
391
    if (mySocket != -1)
Line 501... Line 407...
501
}
407
}
502
 
408
 
503
void AsyncSocket::startEvent()
409
void AsyncSocket::startEvent()
504
{
410
{
505
    myEventSemaphore.lock();
411
    myEventSemaphore.lock();
-
 
412
}
-
 
413
 
-
 
414
bool AsyncSocket::availableEvent()
-
 
415
{
-
 
416
    return (myEventQueue.size() > 0);
506
}
417
}
507
 
418
 
508
int AsyncSocket::getEvent()
419
int AsyncSocket::getEvent()
509
{
420
{
510
    int event = myEvent;
-
 
511
    myEvent = ASYNCSOCKET_EVENT_NONE;
-
 
512
    return event;
421
    return myEventQueue.pop();
513
}
422
}
514
 
423
 
515
void AsyncSocket::waitForEvent()
424
void AsyncSocket::waitForEvent()
516
{
425
{
517
    myEventSemaphore.wait();
426
    myEventSemaphore.wait();
518
}
427
}
519
 
428
 
520
void AsyncSocket::stopEvent()
429
void AsyncSocket::stopEvent()
521
{
430
{
522
    myEventSemaphore.unlock();
431
    myEventSemaphore.unlock();
523
}
432
}
524
 
433
 
525
void AsyncSocket::setAddress(string address, int port)
434
void AsyncSocket::setAddress(string address, int port)
526
{
435
{
527
    myAddress = address;
436
    myAddress = address;
528
    myPort = port;
437
    myPort = port;
Line 534... Line 443...
534
}
443
}
535
 
444
 
536
void AsyncSocket::setSocket(int socket)
445
void AsyncSocket::setSocket(int socket)
537
{
446
{
538
    mySocket = socket;
447
    mySocket = socket;
539
}
448
}
540
 
449
 
541
int AsyncSocket::getSocket()
450
int AsyncSocket::getSocket()
542
{
451
{
543
    return mySocket;
452
    return mySocket;
544
}
453
}
545
 
454
 
546
bool AsyncSocket::availableData()
455
bool AsyncSocket::availableData()
547
{
456
{
548
    return (myInQueue.size() > 0);
457
    return (myInQueue.size() > 0);
549
}
458
}
550
 
459
 
551
string AsyncSocket::getData()
460
string AsyncSocket::getData()
552
{
461
{
553
    return myInQueue.pop();
462
    return myInQueue.pop();
554
}
463
}
555
 
464
 
556
bool AsyncSocket::sendData(string data)
465
bool AsyncSocket::sendData(string data)
557
{
466
{
-
 
467
    //cout << "SendData on " + myAddress + ":" + itos(myPort) + ".\n";
-
 
468
    sendDataDirect(data);
558
    myOutQueue.push(data);
469
    //myOutQueue.push(data);
559
    mySemaphore.broadcast();
470
    //mySemaphore.broadcast();
560
    return true;
471
    return true;
561
}
472
}
562
 
473
 
563
void AsyncSocket::sendDataDirect(string data)
474
void AsyncSocket::sendDataDirect(string data)
564
{
475
{
Line 568... Line 479...
568
 
479
 
569
    int status = ::send(mySocket, data.c_str(), data.size(), 0);
480
    int status = ::send(mySocket, data.c_str(), data.size(), 0);
570
 
481
 
571
    //slog << "Status: " << status << "\n";
482
    //slog << "Status: " << status << "\n";
572
 
483
 
-
 
484
    try
-
 
485
    {
573
    if (status == -1)
486
        if (status == -1)
574
    {
487
        {
575
        switch (errno)
488
            switch (errno)
576
        {
489
            {
577
            case EACCES:
490
                case EACCES:
578
            throw new SocketException("(For  Unix  domain sockets, which are identified by pathname) Write permission is denied on the destination socket file, or search permission is denied for one of the directories the path prefix.  (See path_resolution(7).)");
491
                throw new SocketException("(For  Unix  domain sockets, which are identified by pathname) Write permission is denied on the destination socket file, or search permission is denied for one of the directories the path prefix.  (See path_resolution(7).)");
579
 
492
 
580
            case EAGAIN:
493
                case EAGAIN:
581
            //slog << "The socket is marked non-blocking and the requested operation would block.\n";
494
                //slog << "The socket is marked non-blocking and the requested operation would block.\n";
582
            break;
495
                break;
583
 
496
 
584
            case EBADF:
497
                case EBADF:
585
            throw new SocketException("An invalid descriptor was specified.");
498
                throw new SocketException("An invalid descriptor was specified.");
586
 
499
 
587
            case ECONNRESET:
500
                case ECONNRESET:
Line 593... Line 506...
593
            case EFAULT:
506
                case EFAULT:
594
            throw new SocketException("An invalid user space address was specified for an argument.");
507
                throw new SocketException("An invalid user space address was specified for an argument.");
595
 
508
 
596
            case EINTR:
509
                case EINTR:
597
            throw new SocketException("A signal occurred before any data was transmitted; see signal(7).");
510
                throw new SocketException("A signal occurred before any data was transmitted; see signal(7).");
598
 
511
 
599
            case EINVAL:
512
                case EINVAL:
600
            throw new SocketException("1Invalid argument passed.");
513
                throw new SocketException("1Invalid argument passed.");
601
 
514
 
602
            case EISCONN:
515
                case EISCONN:
603
            throw new SocketException("The connection-mode socket was connected already but a recipient was specified. (Now either this error is returned, or the recipient specification is ignored.)");
516
                throw new SocketException("The connection-mode socket was connected already but a recipient was specified. (Now either this error is returned, or the recipient specification is ignored.)");
Line 617... Line 530...
617
            case ENOTSOCK:
530
                case ENOTSOCK:
618
            throw new SocketException("The argument s is not a socket.");
531
                throw new SocketException("The argument s is not a socket.");
619
 
532
 
620
            case EOPNOTSUPP:
533
                case EOPNOTSUPP:
621
            throw new SocketException("Some bit in the flags argument is inappropriate for the socket type.");
534
                throw new SocketException("Some bit in the flags argument is inappropriate for the socket type.");
622
 
535
 
623
            case EPIPE:
536
                case EPIPE:
624
            throw new SocketException("The  local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.");
537
                throw new SocketException("The  local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.");
625
 
538
 
626
            default:
539
                default:
627
            slog << "Unknow exception: " + itos(errno) + "\n";
540
                slog << "Unknow exception: " + itos(errno) + "\n";
628
            break;
541
                break;
629
        }
542
            }
630
    }
543
        }
-
 
544
    }
-
 
545
    catch (SocketException *e)
-
 
546
    {
-
 
547
        slog << "sendDataDirect: Exception: " + e->getDescription() + "\n";
-
 
548
    }
631
}
549
}
632
 
550
 
633
void AsyncSocket::setEvent(int event)
551
void AsyncSocket::setEvent(int event)
634
{
552
{
635
    myEventSemaphore.lock();
-
 
636
    myEvent = event;
553
    myEventQueue.push(event);
637
    myEventSemaphore.unlock();
-
 
638
    myEventSemaphore.broadcast();
554
    myEventSemaphore.broadcast();
639
}
555
}
640
 
556
 
641
void AsyncSocket::forceReconnect()
557
void AsyncSocket::forceReconnect()
642
{
558
{
-
 
559
    ///FIXME: Threadsafe?
643
    myForceReconnect = true;
560
    myForceReconnect = true;
644
    mySemaphore.broadcast();
-
 
645
}
561
}
646
 
-
 
647
void AsyncSocket::signalHandler(int signum)
-
 
648
{
-
 
649
    //FIXME: We must know which socket is ready to read by using select... 
-
 
650
    cout << "DEBUG: signalHandler signum: " << signum << endl;
-
 
651
 
-
 
652
    map<string, AsyncSocket*>::iterator iter;
-
 
653
 
-
 
654
    mySocketsMutex.lock();
-
 
655
    for (iter = mySockets.begin(); iter != mySockets.end(); iter++)///FIXME: We should check order and length
-
 
656
    {
-
 
657
        cout << "DEBUG: signalHandler: calling: " << iter->second->getId() << endl;
-
 
658
        iter->second->mySemaphore.broadcast();
-
 
659
    }
-
 
660
    mySocketsMutex.unlock();
-
 
661
   
562
 
662
}
-