eventmachine 0.4.5 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/RELEASE_NOTES +17 -1
- data/ext/binder.cpp +17 -1
- data/ext/binder.h +1 -1
- data/ext/cmain.cpp +15 -1
- data/ext/ed.cpp +206 -28
- data/ext/ed.h +18 -1
- data/ext/em.cpp +65 -19
- data/ext/em.h +1 -1
- data/ext/eventmachine.h +2 -1
- data/ext/extconf.rb +52 -3
- data/ext/page.cpp +114 -0
- data/ext/page.h +58 -0
- data/ext/project.h +30 -1
- data/ext/rubymain.cpp +89 -2
- data/ext/sigs.cpp +44 -8
- data/ext/sigs.h +5 -1
- data/ext/ssl.cpp +377 -0
- data/ext/ssl.h +92 -0
- data/lib/eventmachine.rb +39 -7
- metadata +6 -2
data/ext/ed.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: ed.h
|
3
|
+
$Id: ed.h 2445 2006-05-04 21:05:44Z francis $
|
4
4
|
|
5
5
|
File: ed.h
|
6
6
|
Date: 06Apr06
|
@@ -29,6 +29,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
29
29
|
|
30
30
|
|
31
31
|
class EventMachine_t; // forward reference
|
32
|
+
class SslBox_t; // forward reference
|
33
|
+
|
34
|
+
|
35
|
+
bool SetSocketNonblocking (SOCKET);
|
32
36
|
|
33
37
|
|
34
38
|
/*************************
|
@@ -62,6 +66,8 @@ class EventableDescriptor: public Bindable_t
|
|
62
66
|
|
63
67
|
void SetEventCallback (void (*cb)(const char*, int, const char*, int));
|
64
68
|
|
69
|
+
virtual void StartTls() {}
|
70
|
+
|
65
71
|
protected:
|
66
72
|
enum {
|
67
73
|
PendingConnectTimeout = 4 // can easily be made an instance variable
|
@@ -106,6 +112,10 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
106
112
|
// Do we have any data to write? This is used by ShouldDelete.
|
107
113
|
virtual int GetOutboundDataSize() {return OutboundDataSize;}
|
108
114
|
|
115
|
+
virtual void StartTls();
|
116
|
+
void SetServerMode() {bIsServer = true;}
|
117
|
+
|
118
|
+
|
109
119
|
protected:
|
110
120
|
struct OutboundPage {
|
111
121
|
OutboundPage (const char *b, int l, int o=0): Buffer(b), Length(l), Offset(o) {}
|
@@ -121,8 +131,15 @@ class ConnectionDescriptor: public EventableDescriptor
|
|
121
131
|
deque<OutboundPage> OutboundPages;
|
122
132
|
int OutboundDataSize;
|
123
133
|
|
134
|
+
SslBox_t *SslBox;
|
135
|
+
bool bIsServer;
|
136
|
+
|
124
137
|
private:
|
125
138
|
void _WriteOutboundData();
|
139
|
+
void _DispatchInboundData (const char *buffer, int size);
|
140
|
+
void _DispatchCiphertext();
|
141
|
+
int _SendRawOutboundData (const char*, int);
|
142
|
+
|
126
143
|
};
|
127
144
|
|
128
145
|
|
data/ext/em.cpp
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: em.cpp
|
3
|
+
$Id: em.cpp 2457 2006-05-05 14:57:21Z francis $
|
4
4
|
|
5
5
|
File: ed.cpp
|
6
6
|
Date: 06Apr06
|
@@ -82,6 +82,10 @@ EventMachine_t::Run
|
|
82
82
|
|
83
83
|
void EventMachine_t::Run()
|
84
84
|
{
|
85
|
+
#ifdef OS_WIN32
|
86
|
+
HookControlC (true);
|
87
|
+
#endif
|
88
|
+
|
85
89
|
while (true) {
|
86
90
|
gCurrentLoopTime = time(NULL);
|
87
91
|
if (!_RunTimers())
|
@@ -92,6 +96,10 @@ void EventMachine_t::Run()
|
|
92
96
|
if (gTerminateSignalReceived)
|
93
97
|
break;
|
94
98
|
}
|
99
|
+
|
100
|
+
#ifdef OS_WIN32
|
101
|
+
HookControlC (false);
|
102
|
+
#endif
|
95
103
|
}
|
96
104
|
|
97
105
|
|
@@ -111,8 +119,13 @@ bool EventMachine_t::_RunOnce()
|
|
111
119
|
|
112
120
|
//cerr << "X";
|
113
121
|
if (Descriptors.size() == 0) {
|
122
|
+
#ifdef OS_UNIX
|
114
123
|
timeval tv = {0, 200 * 1000};
|
115
124
|
select (0, NULL, NULL, NULL, &tv);
|
125
|
+
#endif
|
126
|
+
#ifdef OS_WIN32
|
127
|
+
Sleep (200);
|
128
|
+
#endif
|
116
129
|
return true;
|
117
130
|
}
|
118
131
|
|
@@ -128,7 +141,7 @@ bool EventMachine_t::_RunOnce()
|
|
128
141
|
EventableDescriptor *ed = Descriptors[i];
|
129
142
|
assert (ed);
|
130
143
|
int sd = ed->GetSocket();
|
131
|
-
assert (sd !=
|
144
|
+
assert (sd != INVALID_SOCKET);
|
132
145
|
|
133
146
|
if (ed->SelectForRead())
|
134
147
|
FD_SET (sd, &fdreads);
|
@@ -148,7 +161,7 @@ bool EventMachine_t::_RunOnce()
|
|
148
161
|
EventableDescriptor *ed = Descriptors[i];
|
149
162
|
assert (ed);
|
150
163
|
int sd = ed->GetSocket();
|
151
|
-
assert (sd !=
|
164
|
+
assert (sd != INVALID_SOCKET);
|
152
165
|
|
153
166
|
if (FD_ISSET (sd, &fdwrites))
|
154
167
|
ed->Write();
|
@@ -294,18 +307,19 @@ const char *EventMachine_t::ConnectToServer (const char *server, int port)
|
|
294
307
|
pin.sin_port = htons (port);
|
295
308
|
|
296
309
|
int sd = socket (AF_INET, SOCK_STREAM, 0);
|
297
|
-
if (sd ==
|
310
|
+
if (sd == INVALID_SOCKET)
|
298
311
|
return NULL;
|
299
312
|
|
300
313
|
// From here on, ALL error returns must close the socket.
|
301
314
|
// Set the new socket nonblocking.
|
302
|
-
|
303
|
-
|
304
|
-
close (sd);
|
315
|
+
if (!SetSocketNonblocking (sd)) {
|
316
|
+
closesocket (sd);
|
305
317
|
return NULL;
|
306
318
|
}
|
307
319
|
|
308
320
|
const char *out = NULL;
|
321
|
+
|
322
|
+
#ifdef OS_UNIX
|
309
323
|
if (connect (sd, (sockaddr*)&pin, sizeof pin) == 0) {
|
310
324
|
// This is a connect success, which Linux appears
|
311
325
|
// never to give when the socket is nonblocking,
|
@@ -338,9 +352,37 @@ const char *EventMachine_t::ConnectToServer (const char *server, int port)
|
|
338
352
|
else {
|
339
353
|
// The error from connect was something other then EINPROGRESS.
|
340
354
|
}
|
355
|
+
#endif
|
356
|
+
|
357
|
+
#ifdef OS_WIN32
|
358
|
+
if (connect (sd, (sockaddr*)&pin, sizeof pin) == 0) {
|
359
|
+
// This is a connect success, which Windows appears
|
360
|
+
// never to give when the socket is nonblocking,
|
361
|
+
// even if the connection is intramachine or to
|
362
|
+
// localhost.
|
363
|
+
throw std::runtime_error ("unimplemented");
|
364
|
+
}
|
365
|
+
else if (WSAGetLastError() == WSAEWOULDBLOCK) {
|
366
|
+
// Here, there's no disposition.
|
367
|
+
// Windows appears not to surface refused connections or
|
368
|
+
// such stuff at this point.
|
369
|
+
// Put the connection on the stack and wait for it to complete
|
370
|
+
// or time out.
|
371
|
+
ConnectionDescriptor *cd = new ConnectionDescriptor (sd);
|
372
|
+
if (!cd)
|
373
|
+
throw std::runtime_error ("no connection allocated");
|
374
|
+
cd->SetConnectPending (true);
|
375
|
+
Add (cd);
|
376
|
+
out = cd->GetBinding().c_str();
|
377
|
+
}
|
378
|
+
else {
|
379
|
+
// The error from connect was something other then WSAEWOULDBLOCK.
|
380
|
+
}
|
381
|
+
|
382
|
+
#endif
|
341
383
|
|
342
384
|
if (out == NULL)
|
343
|
-
|
385
|
+
closesocket (sd);
|
344
386
|
return out;
|
345
387
|
}
|
346
388
|
|
@@ -362,7 +404,7 @@ const char *EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
362
404
|
struct sockaddr_in sin;
|
363
405
|
|
364
406
|
int sd_accept = socket (AF_INET, SOCK_STREAM, 0);
|
365
|
-
if (sd_accept ==
|
407
|
+
if (sd_accept == INVALID_SOCKET) {
|
366
408
|
goto fail;
|
367
409
|
}
|
368
410
|
|
@@ -391,11 +433,13 @@ const char *EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
391
433
|
}
|
392
434
|
}
|
393
435
|
|
394
|
-
{ // set CLOEXEC.
|
436
|
+
{ // set CLOEXEC. Only makes sense on Unix
|
437
|
+
#ifdef OS_UNIX
|
395
438
|
int cloexec = fcntl (sd_accept, F_GETFD, 0);
|
396
439
|
assert (cloexec >= 0);
|
397
440
|
cloexec |= FD_CLOEXEC;
|
398
441
|
fcntl (sd_accept, F_SETFD, cloexec);
|
442
|
+
#endif
|
399
443
|
}
|
400
444
|
|
401
445
|
|
@@ -412,8 +456,9 @@ const char *EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
412
456
|
{
|
413
457
|
// Set the acceptor non-blocking.
|
414
458
|
// THIS IS CRUCIALLY IMPORTANT because we read it in a select loop.
|
415
|
-
|
416
|
-
|
459
|
+
if (!SetSocketNonblocking (sd_accept)) {
|
460
|
+
//int val = fcntl (sd_accept, F_GETFL, 0);
|
461
|
+
//if (fcntl (sd_accept, F_SETFL, val | O_NONBLOCK) == -1) {
|
417
462
|
goto fail;
|
418
463
|
}
|
419
464
|
}
|
@@ -429,8 +474,8 @@ const char *EventMachine_t::CreateTcpServer (const char *server, int port)
|
|
429
474
|
return output_binding;
|
430
475
|
|
431
476
|
fail:
|
432
|
-
if (sd_accept !=
|
433
|
-
|
477
|
+
if (sd_accept != INVALID_SOCKET)
|
478
|
+
closesocket (sd_accept);
|
434
479
|
return NULL;
|
435
480
|
}
|
436
481
|
|
@@ -444,7 +489,7 @@ const char *EventMachine_t::OpenDatagramSocket (const char *address, int port)
|
|
444
489
|
const char *output_binding = NULL;
|
445
490
|
|
446
491
|
int sd = socket (AF_INET, SOCK_DGRAM, 0);
|
447
|
-
if (sd ==
|
492
|
+
if (sd == INVALID_SOCKET)
|
448
493
|
goto fail;
|
449
494
|
// from here on, early returns must close the socket!
|
450
495
|
|
@@ -470,8 +515,9 @@ const char *EventMachine_t::OpenDatagramSocket (const char *address, int port)
|
|
470
515
|
|
471
516
|
// Set the new socket nonblocking.
|
472
517
|
{
|
473
|
-
|
474
|
-
|
518
|
+
if (!SetSocketNonblocking (sd))
|
519
|
+
//int val = fcntl (sd, F_GETFL, 0);
|
520
|
+
//if (fcntl (sd, F_SETFL, val | O_NONBLOCK) == -1)
|
475
521
|
goto fail;
|
476
522
|
}
|
477
523
|
|
@@ -489,8 +535,8 @@ const char *EventMachine_t::OpenDatagramSocket (const char *address, int port)
|
|
489
535
|
return output_binding;
|
490
536
|
|
491
537
|
fail:
|
492
|
-
if (sd !=
|
493
|
-
|
538
|
+
if (sd != INVALID_SOCKET)
|
539
|
+
closesocket (sd);
|
494
540
|
return NULL;
|
495
541
|
}
|
496
542
|
|
data/ext/em.h
CHANGED
data/ext/eventmachine.h
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*****************************************************************************
|
2
2
|
|
3
|
-
$Id: eventmachine.h
|
3
|
+
$Id: eventmachine.h 2421 2006-04-29 23:48:49Z francis $
|
4
4
|
|
5
5
|
File: eventmachine.h
|
6
6
|
Date: 15Apr06
|
@@ -38,6 +38,7 @@ extern "C" {
|
|
38
38
|
const char *evma_connect_to_server (const char *server, int port);
|
39
39
|
const char *evma_create_tcp_server (const char *address, int port);
|
40
40
|
const char *evma_open_datagram_socket (const char *server, int port);
|
41
|
+
void evma_start_tls (const char *binding);
|
41
42
|
int evma_send_data_to_connection (const char *binding, const char *data, int data_length);
|
42
43
|
int evma_send_datagram (const char *binding, const char *data, int data_length, const char *address, int port);
|
43
44
|
void evma_close_connection (const char *binding, int after_writing);
|
data/ext/extconf.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# $Id: extconf.rb
|
1
|
+
# $Id: extconf.rb 2451 2006-05-05 03:16:31Z francis $
|
2
2
|
#
|
3
3
|
#----------------------------------------------------------------------------
|
4
4
|
#
|
@@ -27,6 +27,55 @@
|
|
27
27
|
#
|
28
28
|
|
29
29
|
require 'mkmf'
|
30
|
-
|
31
|
-
|
30
|
+
|
31
|
+
flags = []
|
32
|
+
|
33
|
+
case RUBY_PLATFORM.split('-',2)[1]
|
34
|
+
when 'mswin32', 'mingw32', 'bccwin32'
|
35
|
+
unless have_header('windows.h') and
|
36
|
+
have_header('winsock.h') and
|
37
|
+
have_library('kernel32') and
|
38
|
+
have_library('rpcrt4') and
|
39
|
+
have_library('gdi32')
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
flags << "-D OS_WIN32"
|
44
|
+
flags << "-GX"
|
45
|
+
flags << "-GR"
|
46
|
+
|
47
|
+
if have_library('ssleay32') and
|
48
|
+
have_library('libeay32') and
|
49
|
+
have_header('openssl/ssl.h') and
|
50
|
+
have_header('openssl/err.h')
|
51
|
+
flags << '-D WITH_SSL'
|
52
|
+
else
|
53
|
+
flags << '-D WITHOUT_SSL'
|
54
|
+
end
|
55
|
+
else
|
56
|
+
unless have_library('pthread')
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
|
60
|
+
flags << '-D OS_UNIX'
|
61
|
+
|
62
|
+
if have_library('ssl') and
|
63
|
+
have_library('crypto') and
|
64
|
+
have_header('openssl/ssl.h') and
|
65
|
+
have_header('openssl/err.h')
|
66
|
+
flags << '-D WITH_SSL'
|
67
|
+
else
|
68
|
+
flags << '-D WITHOUT_SSL'
|
69
|
+
end
|
70
|
+
# on Unix we need a g++ link, not gcc.
|
71
|
+
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
72
|
+
end
|
73
|
+
|
74
|
+
if $CPPFLAGS
|
75
|
+
$CPPFLAGS += flags.join(' ')
|
76
|
+
else
|
77
|
+
$CFLAGS + flags.join(' ')
|
78
|
+
end
|
79
|
+
|
80
|
+
|
32
81
|
create_makefile "rubyeventmachine"
|
data/ext/page.cpp
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
/*****************************************************************************
|
2
|
+
|
3
|
+
$Id: page.cpp 2426 2006-04-30 00:21:48Z francis $
|
4
|
+
|
5
|
+
File: page.cpp
|
6
|
+
Date: 30Apr06
|
7
|
+
|
8
|
+
Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
|
9
|
+
Gmail: garbagecat20
|
10
|
+
|
11
|
+
This program is free software; you can redistribute it and/or modify
|
12
|
+
it under the terms of the GNU General Public License as published by
|
13
|
+
the Free Software Foundation; either version 2 of the License, or
|
14
|
+
(at your option) any later version.
|
15
|
+
|
16
|
+
This program is distributed in the hope that it will be useful,
|
17
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
18
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
19
|
+
GNU General Public License for more details.
|
20
|
+
|
21
|
+
You should have received a copy of the GNU General Public License
|
22
|
+
along with this program; if not, write to the Free Software
|
23
|
+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
24
|
+
|
25
|
+
*****************************************************************************/
|
26
|
+
|
27
|
+
|
28
|
+
#include "project.h"
|
29
|
+
|
30
|
+
|
31
|
+
/******************
|
32
|
+
PageList::PageList
|
33
|
+
******************/
|
34
|
+
|
35
|
+
PageList::PageList()
|
36
|
+
{
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
/*******************
|
41
|
+
PageList::~PageList
|
42
|
+
*******************/
|
43
|
+
|
44
|
+
PageList::~PageList()
|
45
|
+
{
|
46
|
+
while (HasPages())
|
47
|
+
PopFront();
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
/***************
|
52
|
+
PageList::Front
|
53
|
+
***************/
|
54
|
+
|
55
|
+
void PageList::Front (const char **page, int *length)
|
56
|
+
{
|
57
|
+
assert (page && length);
|
58
|
+
|
59
|
+
if (HasPages()) {
|
60
|
+
Page p = Pages.front();
|
61
|
+
*page = p.Buffer;
|
62
|
+
*length = p.Size;
|
63
|
+
}
|
64
|
+
else {
|
65
|
+
*page = NULL;
|
66
|
+
*length = 0;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
/******************
|
72
|
+
PageList::PopFront
|
73
|
+
******************/
|
74
|
+
|
75
|
+
void PageList::PopFront()
|
76
|
+
{
|
77
|
+
if (HasPages()) {
|
78
|
+
Page p = Pages.front();
|
79
|
+
Pages.pop_front();
|
80
|
+
if (p.Buffer)
|
81
|
+
free ((void*)p.Buffer);
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
/******************
|
87
|
+
PageList::HasPages
|
88
|
+
******************/
|
89
|
+
|
90
|
+
bool PageList::HasPages()
|
91
|
+
{
|
92
|
+
return (Pages.size() > 0) ? true : false;
|
93
|
+
}
|
94
|
+
|
95
|
+
|
96
|
+
/**************
|
97
|
+
PageList::Push
|
98
|
+
**************/
|
99
|
+
|
100
|
+
void PageList::Push (const char *buf, int size)
|
101
|
+
{
|
102
|
+
if (buf && (size > 0)) {
|
103
|
+
char *copy = (char*) malloc (size);
|
104
|
+
if (!copy)
|
105
|
+
throw runtime_error ("no memory in pagelist");
|
106
|
+
memcpy (copy, buf, size);
|
107
|
+
Pages.push_back (Page (copy, size));
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|