sensu-em 2.4.1 → 2.5.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +15 -5
- data/CHANGELOG.md +41 -1
- data/README.md +2 -3
- data/eventmachine.gemspec +2 -1
- data/ext/cmain.cpp +19 -3
- data/ext/ed.cpp +22 -8
- data/ext/em.cpp +123 -76
- data/ext/em.h +40 -6
- data/ext/eventmachine.h +2 -0
- data/ext/extconf.rb +16 -2
- data/ext/fastfilereader/extconf.rb +3 -0
- data/ext/fastfilereader/mapper.cpp +1 -1
- data/ext/project.h +11 -7
- data/ext/rubymain.cpp +38 -2
- data/ext/ssl.cpp +4 -1
- data/ext/ssl.h +4 -0
- data/java/src/com/rubyeventmachine/EventableChannel.java +8 -1
- data/lib/em/buftok.rb +34 -85
- data/lib/em/protocols/httpclient.rb +31 -11
- data/lib/em/protocols/line_and_text.rb +2 -3
- data/lib/em/protocols/linetext2.rb +0 -1
- data/lib/em/protocols/smtpserver.rb +32 -9
- data/lib/em/pure_ruby.rb +2 -2
- data/lib/em/tick_loop.rb +19 -19
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +12 -4
- data/lib/jeventmachine.rb +22 -6
- data/rakelib/package.rake +1 -1
- data/tests/em_test_helper.rb +4 -0
- data/tests/test_attach.rb +1 -0
- data/tests/test_basic.rb +14 -16
- data/tests/test_completion.rb +1 -0
- data/tests/test_connection_count.rb +1 -0
- data/tests/test_connection_write.rb +35 -0
- data/tests/test_epoll.rb +11 -14
- data/tests/test_httpclient.rb +43 -0
- data/tests/test_iterator.rb +6 -6
- data/tests/test_kb.rb +19 -25
- data/tests/test_many_fds.rb +22 -0
- data/tests/test_pause.rb +7 -2
- data/tests/test_pool.rb +2 -0
- data/tests/test_process_watch.rb +2 -0
- data/tests/test_processes.rb +7 -7
- data/tests/test_resolver.rb +33 -7
- data/tests/test_ssl_methods.rb +3 -4
- data/tests/test_ssl_verify.rb +62 -62
- data/tests/test_threaded_resource.rb +8 -0
- data/tmp/java/rubyeventmachine/.build +0 -0
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52263bd3723537a9a721e556dd5516e9cda1fee7
|
4
|
+
data.tar.gz: ee762853b84222141bc65da790af811eaf914cb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c23f57da24c2c4b6da1fdb2b1e6fb76b6defc6738bef5bbdbda6b123e879445db1b78db18aa7f73cda65dfd99d656dc4f2b54c3586b80eb504ffbdbc42ea2aef
|
7
|
+
data.tar.gz: e9265b41b73569cf3a61714380cd9de97c2a81e1d9c7438e77b4c27b572f19eda138503dbde7976a5b48f78f423d211c7411b98b261535e9cbf6d864f55facd4
|
data/.travis.yml
CHANGED
@@ -1,12 +1,22 @@
|
|
1
|
-
script: rake compile test
|
1
|
+
script: bundle exec rake compile test
|
2
|
+
env:
|
3
|
+
global:
|
4
|
+
- TESTOPTS=-v
|
2
5
|
language: ruby
|
6
|
+
sudo: false
|
3
7
|
rvm:
|
4
8
|
- 1.8.7
|
9
|
+
- 1.9.2
|
5
10
|
- 1.9.3
|
6
|
-
-
|
7
|
-
-
|
11
|
+
- 2.0.0
|
12
|
+
- 2.1
|
13
|
+
- 2.2
|
14
|
+
- rbx
|
8
15
|
- jruby
|
9
16
|
matrix:
|
10
17
|
allow_failures:
|
11
|
-
- rvm: rbx
|
12
|
-
- rvm:
|
18
|
+
- rvm: rbx
|
19
|
+
- rvm: jruby
|
20
|
+
include:
|
21
|
+
- rvm: 2.0.0
|
22
|
+
os: osx
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,46 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 1.0.
|
3
|
+
## 1.0.7 (February 10, 2015)
|
4
|
+
* fix delay in kqueue/epoll reactor shutdown when timers exist [#587]
|
5
|
+
* fix memory leak introduced in v1.0.5 [#586]
|
6
|
+
* expose EM.set_simultaneous_accept_count [#420]
|
7
|
+
* fix busy loop when EM.run and EM.next_tick are invoked from exception handler [#452]
|
8
|
+
|
9
|
+
## 1.0.6 (February 3, 2015)
|
10
|
+
* add support for Rubinius Process::Status [#568]
|
11
|
+
* small bugfixes for SmtpServer [#449]
|
12
|
+
* update buftok.rb [#547]
|
13
|
+
* fix assertion on Write() [#525]
|
14
|
+
* work around mkmf.rb bug preventing gem installation [#574]
|
15
|
+
* add pause/resume support to jruby reactor [#556]
|
16
|
+
* fix pure ruby reactor to use 127.0.0.1 instead of localhost [#439]
|
17
|
+
* fix compilation under macruby [#243]
|
18
|
+
* add chunked encoding to http client [#111]
|
19
|
+
* fix errors on win32 when dealing with pipes [1ea45498] [#105]
|
20
|
+
|
21
|
+
## 1.0.5 (February 2, 2015)
|
22
|
+
* use monotonic clocks on Linux, OS X, Solaris, and Windows [#563]
|
23
|
+
* use the rb_fd_* API to get autosized fd_sets [#502]
|
24
|
+
* add basic tests that the DNS resolver isn't leaking timers [#571]
|
25
|
+
* update to test-unit 2.x and improve various unit tests [#551]
|
26
|
+
* remove EventMachine_t::Popen code marked by ifdef OBSOLETE [#551]
|
27
|
+
* ruby 2.0 may fail at Queue.pop, so rescue and complain to $stderr [#551]
|
28
|
+
* set file handle to INVALID_HANDLE_VALUE after closing the file [#565]
|
29
|
+
* use `defined?` instead of rescuing NameError for flow control [#535]
|
30
|
+
* fix closing files and sockets on Windows [#564]
|
31
|
+
* fix file uploads in Windows [#562]
|
32
|
+
* catch failure to fork [#539]
|
33
|
+
* use chunks for SSL write [#545]
|
34
|
+
|
35
|
+
## 1.0.4 (December 19, 2014)
|
36
|
+
* add starttls_options to smtp server [#552]
|
37
|
+
* fix closesocket on windows [#497]
|
38
|
+
* fix build on ruby 2.2 [#503]
|
39
|
+
* fix build error on ruby 1.9 [#508]
|
40
|
+
* fix timer leak during dns resolution [#489]
|
41
|
+
* add concurrency validation to EM::Iterator [#468]
|
42
|
+
* add get_file_descriptor to get fd for a signature [#467]
|
43
|
+
* add EM.attach_server and EM.attach_socket_server [#465, #466]
|
4
44
|
* calling pause from receive_data takes effect immediately [#464]
|
5
45
|
* reactor_running? returns false after fork [#455]
|
6
46
|
* fix infinite loop on double close [edc4d0e6, #441, #445]
|
data/README.md
CHANGED
@@ -86,7 +86,7 @@ Here's a fully-functional echo server written with EventMachine:
|
|
86
86
|
|
87
87
|
## EventMachine documentation ##
|
88
88
|
|
89
|
-
Currently we only have [reference documentation](http://eventmachine
|
89
|
+
Currently we only have [reference documentation](http://rdoc.info/github/eventmachine/eventmachine/frames) and a [wiki](https://github.com/eventmachine/eventmachine/wiki).
|
90
90
|
|
91
91
|
|
92
92
|
## Community and where to get help ##
|
@@ -105,5 +105,4 @@ Copyright: (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
|
|
105
105
|
|
106
106
|
## Alternatives ##
|
107
107
|
|
108
|
-
If you are unhappy with EventMachine and want to use Ruby, check out [
|
109
|
-
One caveat: by May 2011, it did not support JRuby and Windows.
|
108
|
+
If you are unhappy with EventMachine and want to use Ruby, check out [Celluloid](https://celluloid.io/).
|
data/eventmachine.gemspec
CHANGED
@@ -5,7 +5,7 @@ require "em/version"
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = 'sensu-em'
|
8
|
-
s.version = '2.
|
8
|
+
s.version = '2.5.0.beta'
|
9
9
|
s.homepage = 'http://rubyeventmachine.com'
|
10
10
|
s.rubyforge_project = 'eventmachine'
|
11
11
|
s.licenses = ["Ruby", "GPL"]
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
|
18
18
|
|
19
|
+
s.add_development_dependency 'test-unit', '~> 2.0'
|
19
20
|
s.add_development_dependency 'rake-compiler', '~> 0.8.3'
|
20
21
|
s.add_development_dependency 'yard', ">= 0.8.5.2"
|
21
22
|
s.add_development_dependency 'bluecloth' unless RUBY_PLATFORM =~ /java/
|
data/ext/cmain.cpp
CHANGED
@@ -653,7 +653,6 @@ extern "C" int evma_get_max_timer_count()
|
|
653
653
|
return EventMachine_t::GetMaxTimerCount();
|
654
654
|
}
|
655
655
|
|
656
|
-
|
657
656
|
/************************
|
658
657
|
evma_set_max_timer_count
|
659
658
|
************************/
|
@@ -671,6 +670,21 @@ extern "C" void evma_set_max_timer_count (int ct)
|
|
671
670
|
EventMachine_t::SetMaxTimerCount (ct);
|
672
671
|
}
|
673
672
|
|
673
|
+
/******************
|
674
|
+
evma_get/set_simultaneous_accept_count
|
675
|
+
******************/
|
676
|
+
|
677
|
+
extern "C" void evma_set_simultaneous_accept_count (int count)
|
678
|
+
{
|
679
|
+
EventMachine_t::SetSimultaneousAcceptCount(count);
|
680
|
+
}
|
681
|
+
|
682
|
+
extern "C" int evma_get_simultaneous_accept_count()
|
683
|
+
{
|
684
|
+
return EventMachine_t::GetSimultaneousAcceptCount();
|
685
|
+
}
|
686
|
+
|
687
|
+
|
674
688
|
/******************
|
675
689
|
evma_setuid_string
|
676
690
|
******************/
|
@@ -762,8 +776,11 @@ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, c
|
|
762
776
|
|
763
777
|
ensure_eventmachine("evma_send_file_data_to_connection");
|
764
778
|
|
779
|
+
#if defined(OS_WIN32)
|
780
|
+
int Fd = open (filename, O_RDONLY|O_BINARY);
|
781
|
+
#else
|
765
782
|
int Fd = open (filename, O_RDONLY);
|
766
|
-
|
783
|
+
#endif
|
767
784
|
if (Fd < 0)
|
768
785
|
return errno;
|
769
786
|
// From here on, all early returns MUST close Fd.
|
@@ -785,7 +802,6 @@ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, c
|
|
785
802
|
return -1;
|
786
803
|
}
|
787
804
|
|
788
|
-
|
789
805
|
r = read (Fd, data, filesize);
|
790
806
|
if (r != filesize) {
|
791
807
|
int e = errno;
|
data/ext/ed.cpp
CHANGED
@@ -567,11 +567,25 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
|
|
567
567
|
#ifdef WITH_SSL
|
568
568
|
if (SslBox) {
|
569
569
|
if (length > 0) {
|
570
|
-
int
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
570
|
+
int writed = 0;
|
571
|
+
char *p = (char*)data;
|
572
|
+
|
573
|
+
while (writed < length) {
|
574
|
+
int to_write = SSLBOX_INPUT_CHUNKSIZE;
|
575
|
+
int remaining = length - writed;
|
576
|
+
|
577
|
+
if (remaining < SSLBOX_INPUT_CHUNKSIZE)
|
578
|
+
to_write = remaining;
|
579
|
+
|
580
|
+
int w = SslBox->PutPlaintext (p, to_write);
|
581
|
+
if (w < 0) {
|
582
|
+
ScheduleClose (false);
|
583
|
+
}else
|
584
|
+
_DispatchCiphertext();
|
585
|
+
|
586
|
+
p += to_write;
|
587
|
+
writed += to_write;
|
588
|
+
}
|
575
589
|
}
|
576
590
|
// TODO: What's the correct return value?
|
577
591
|
return 1; // That's a wild guess, almost certainly wrong.
|
@@ -603,7 +617,6 @@ int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
|
|
603
617
|
|
604
618
|
if (IsCloseScheduled())
|
605
619
|
return 0;
|
606
|
-
|
607
620
|
// 25Mar10: Ignore 0 length packets as they are not meaningful in TCP (as opposed to UDP)
|
608
621
|
// and can cause the assert(nbytes>0) to fail when OutboundPages has a bunch of 0 length pages.
|
609
622
|
if (length == 0)
|
@@ -1230,7 +1243,7 @@ void ConnectionDescriptor::_DispatchCiphertext()
|
|
1230
1243
|
assert (SslBox);
|
1231
1244
|
|
1232
1245
|
|
1233
|
-
char BigBuf [
|
1246
|
+
char BigBuf [SSLBOX_OUTPUT_CHUNKSIZE];
|
1234
1247
|
bool did_work;
|
1235
1248
|
|
1236
1249
|
do {
|
@@ -1422,8 +1435,9 @@ void AcceptorDescriptor::Read()
|
|
1422
1435
|
|
1423
1436
|
struct sockaddr_in pin;
|
1424
1437
|
socklen_t addrlen = sizeof (pin);
|
1438
|
+
int accept_count = EventMachine_t::GetSimultaneousAcceptCount();
|
1425
1439
|
|
1426
|
-
for (int i=0; i <
|
1440
|
+
for (int i=0; i < accept_count; i++) {
|
1427
1441
|
int sd = accept (GetSocket(), (struct sockaddr*)&pin, &addrlen);
|
1428
1442
|
if (sd == INVALID_SOCKET) {
|
1429
1443
|
// This breaks the loop when we've accepted everything on the kernel queue,
|
data/ext/em.cpp
CHANGED
@@ -27,6 +27,11 @@ See the file COPYING for complete licensing information.
|
|
27
27
|
*/
|
28
28
|
static unsigned int MaxOutstandingTimers = 100000;
|
29
29
|
|
30
|
+
/* The number of accept() done at once in a single tick when the acceptor
|
31
|
+
* socket becomes readable.
|
32
|
+
*/
|
33
|
+
static unsigned int SimultaneousAcceptCount = 10;
|
34
|
+
|
30
35
|
|
31
36
|
/* Internal helper to convert strings to internet addresses. IPv6-aware.
|
32
37
|
* Not reentrant or threadsafe, optimized for speed.
|
@@ -61,6 +66,17 @@ void EventMachine_t::SetMaxTimerCount (int count)
|
|
61
66
|
MaxOutstandingTimers = count;
|
62
67
|
}
|
63
68
|
|
69
|
+
int EventMachine_t::GetSimultaneousAcceptCount()
|
70
|
+
{
|
71
|
+
return SimultaneousAcceptCount;
|
72
|
+
}
|
73
|
+
|
74
|
+
void EventMachine_t::SetSimultaneousAcceptCount (int count)
|
75
|
+
{
|
76
|
+
if (count < 1)
|
77
|
+
count = 1;
|
78
|
+
SimultaneousAcceptCount = count;
|
79
|
+
}
|
64
80
|
|
65
81
|
|
66
82
|
/******************************
|
@@ -68,12 +84,12 @@ EventMachine_t::EventMachine_t
|
|
68
84
|
******************************/
|
69
85
|
|
70
86
|
EventMachine_t::EventMachine_t (EMCallback event_callback):
|
87
|
+
NumCloseScheduled (0),
|
71
88
|
HeartbeatInterval(2000000),
|
72
89
|
EventCallback (event_callback),
|
73
90
|
NextHeartbeatTime (0),
|
74
91
|
LoopBreakerReader (-1),
|
75
92
|
LoopBreakerWriter (-1),
|
76
|
-
NumCloseScheduled (0),
|
77
93
|
bTerminateSignalReceived (false),
|
78
94
|
bEpoll (false),
|
79
95
|
epfd (-1),
|
@@ -85,6 +101,11 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
|
|
85
101
|
Quantum.tv_sec = 0;
|
86
102
|
Quantum.tv_usec = 90000;
|
87
103
|
|
104
|
+
/* Initialize monotonic timekeeping on OS X before the first call to GetRealTime */
|
105
|
+
#ifdef OS_DARWIN
|
106
|
+
(void) mach_timebase_info(&mach_timebase);
|
107
|
+
#endif
|
108
|
+
|
88
109
|
// Make sure the current loop time is sane, in case we do any initializations of
|
89
110
|
// objects before we start running.
|
90
111
|
_UpdateTime();
|
@@ -101,6 +122,7 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
|
|
101
122
|
#endif
|
102
123
|
|
103
124
|
_InitializeLoopBreaker();
|
125
|
+
SelectData = new SelectData_t();
|
104
126
|
}
|
105
127
|
|
106
128
|
|
@@ -130,6 +152,8 @@ EventMachine_t::~EventMachine_t()
|
|
130
152
|
close (epfd);
|
131
153
|
if (kqfd != -1)
|
132
154
|
close (kqfd);
|
155
|
+
|
156
|
+
delete SelectData;
|
133
157
|
}
|
134
158
|
|
135
159
|
|
@@ -187,6 +211,12 @@ void EventMachine_t::ScheduleHalt()
|
|
187
211
|
* The answer is to call evma_stop_machine, which calls here, from a SIGINT handler.
|
188
212
|
*/
|
189
213
|
bTerminateSignalReceived = true;
|
214
|
+
|
215
|
+
/* Signal the loopbreaker so we break out of long-running select/epoll/kqueue and
|
216
|
+
* notice the halt boolean is set. Signalling the loopbreaker also uses a single
|
217
|
+
* signal-safe syscall.
|
218
|
+
*/
|
219
|
+
SignalLoopBreaker();
|
190
220
|
}
|
191
221
|
|
192
222
|
|
@@ -352,16 +382,49 @@ void EventMachine_t::_UpdateTime()
|
|
352
382
|
EventMachine_t::GetRealTime
|
353
383
|
***************************/
|
354
384
|
|
385
|
+
// Two great writeups of cross-platform monotonic time are at:
|
386
|
+
// http://www.python.org/dev/peps/pep-0418
|
387
|
+
// http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking
|
388
|
+
// Uncomment the #pragma messages to confirm which compile-time option was used
|
355
389
|
uint64_t EventMachine_t::GetRealTime()
|
356
390
|
{
|
357
391
|
uint64_t current_time;
|
358
392
|
|
359
|
-
#if defined(
|
393
|
+
#if defined(HAVE_CONST_CLOCK_MONOTONIC_RAW)
|
394
|
+
// #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC_RAW"
|
395
|
+
// Linux 2.6.28 and above
|
396
|
+
struct timespec tv;
|
397
|
+
clock_gettime (CLOCK_MONOTONIC_RAW, &tv);
|
398
|
+
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000));
|
399
|
+
|
400
|
+
#elif defined(HAVE_CONST_CLOCK_MONOTONIC)
|
401
|
+
// #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC"
|
402
|
+
// Linux, FreeBSD 5.0 and above, Solaris 8 and above, OpenBSD, NetBSD, DragonflyBSD
|
403
|
+
struct timespec tv;
|
404
|
+
clock_gettime (CLOCK_MONOTONIC, &tv);
|
405
|
+
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000));
|
406
|
+
|
407
|
+
#elif defined(HAVE_GETHRTIME)
|
408
|
+
// #pragma message "GetRealTime: gethrtime"
|
409
|
+
// Solaris and HP-UX
|
410
|
+
current_time = (uint64_t)gethrtime() / 1000;
|
411
|
+
|
412
|
+
#elif defined(OS_DARWIN)
|
413
|
+
// #pragma message "GetRealTime: mach_absolute_time"
|
414
|
+
// Mac OS X
|
415
|
+
// https://developer.apple.com/library/mac/qa/qa1398/_index.html
|
416
|
+
current_time = mach_absolute_time() * mach_timebase.numer / mach_timebase.denom / 1000;
|
417
|
+
|
418
|
+
#elif defined(OS_UNIX)
|
419
|
+
// #pragma message "GetRealTime: gettimeofday"
|
420
|
+
// Unix fallback
|
360
421
|
struct timeval tv;
|
361
422
|
gettimeofday (&tv, NULL);
|
362
423
|
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)(tv.tv_usec));
|
363
424
|
|
364
425
|
#elif defined(OS_WIN32)
|
426
|
+
// #pragma message "GetRealTime: GetTickCount"
|
427
|
+
// Future improvement: use GetTickCount64 in Windows Vista / Server 2008
|
365
428
|
unsigned tick = GetTickCount();
|
366
429
|
if (tick < LastTickCount)
|
367
430
|
TickCountTickover += 1;
|
@@ -370,6 +433,8 @@ uint64_t EventMachine_t::GetRealTime()
|
|
370
433
|
current_time *= 1000; // convert to microseconds
|
371
434
|
|
372
435
|
#else
|
436
|
+
// #pragma message "GetRealTime: time"
|
437
|
+
// Universal fallback
|
373
438
|
current_time = (uint64_t)time(NULL) * 1000000LL;
|
374
439
|
#endif
|
375
440
|
|
@@ -806,11 +871,17 @@ SelectData_t::SelectData_t
|
|
806
871
|
SelectData_t::SelectData_t()
|
807
872
|
{
|
808
873
|
maxsocket = 0;
|
809
|
-
|
810
|
-
|
811
|
-
|
874
|
+
rb_fd_init (&fdreads);
|
875
|
+
rb_fd_init (&fdwrites);
|
876
|
+
rb_fd_init (&fderrors);
|
812
877
|
}
|
813
878
|
|
879
|
+
SelectData_t::~SelectData_t()
|
880
|
+
{
|
881
|
+
rb_fd_term (&fdreads);
|
882
|
+
rb_fd_term (&fdwrites);
|
883
|
+
rb_fd_term (&fderrors);
|
884
|
+
}
|
814
885
|
|
815
886
|
#ifdef BUILD_FOR_RUBY
|
816
887
|
/*****************
|
@@ -821,7 +892,7 @@ _SelectDataSelect
|
|
821
892
|
static VALUE _SelectDataSelect (void *v)
|
822
893
|
{
|
823
894
|
SelectData_t *sd = (SelectData_t*)v;
|
824
|
-
sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
|
895
|
+
sd->nSockets = select (sd->maxsocket+1, rb_fd_ptr(&(sd->fdreads)), rb_fd_ptr(&(sd->fdwrites)), rb_fd_ptr(&(sd->fderrors)), &(sd->tv));
|
825
896
|
return Qnil;
|
826
897
|
}
|
827
898
|
#endif
|
@@ -833,9 +904,11 @@ SelectData_t::_Select
|
|
833
904
|
int SelectData_t::_Select()
|
834
905
|
{
|
835
906
|
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
907
|
+
// added in ruby 1.9.3
|
836
908
|
rb_thread_call_without_gvl ((void *(*)(void *))_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0);
|
837
909
|
return nSockets;
|
838
910
|
#elif defined(HAVE_TBR)
|
911
|
+
// added in ruby 1.9.1, deprecated in ruby 2.0.0
|
839
912
|
rb_thread_blocking_region (_SelectDataSelect, (void*)this, RUBY_UBF_IO, 0);
|
840
913
|
return nSockets;
|
841
914
|
#else
|
@@ -844,7 +917,13 @@ int SelectData_t::_Select()
|
|
844
917
|
}
|
845
918
|
#endif
|
846
919
|
|
847
|
-
|
920
|
+
void SelectData_t::_Clear()
|
921
|
+
{
|
922
|
+
maxsocket = 0;
|
923
|
+
rb_fd_zero (&fdreads);
|
924
|
+
rb_fd_zero (&fdwrites);
|
925
|
+
rb_fd_zero (&fderrors);
|
926
|
+
}
|
848
927
|
|
849
928
|
/******************************
|
850
929
|
EventMachine_t::_RunSelectOnce
|
@@ -861,23 +940,17 @@ void EventMachine_t::_RunSelectOnce()
|
|
861
940
|
// however it has the same problem interoperating with Ruby
|
862
941
|
// threads that select does.
|
863
942
|
|
864
|
-
|
865
|
-
|
866
|
-
fd_set fdreads, fdwrites;
|
867
|
-
FD_ZERO (&fdreads);
|
868
|
-
FD_ZERO (&fdwrites);
|
869
|
-
|
870
|
-
int maxsocket = 0;
|
871
|
-
*/
|
943
|
+
// Get ready for select()
|
944
|
+
SelectData->_Clear();
|
872
945
|
|
873
946
|
// Always read the loop-breaker reader.
|
874
947
|
// Changed 23Aug06, provisionally implemented for Windows with a UDP socket
|
875
948
|
// running on localhost with a randomly-chosen port. (*Puke*)
|
876
949
|
// Windows has a version of the Unix pipe() library function, but it doesn't
|
877
950
|
// give you back descriptors that are selectable.
|
878
|
-
|
879
|
-
if (SelectData
|
880
|
-
SelectData
|
951
|
+
rb_fd_set (LoopBreakerReader, &(SelectData->fdreads));
|
952
|
+
if (SelectData->maxsocket < LoopBreakerReader)
|
953
|
+
SelectData->maxsocket = LoopBreakerReader;
|
881
954
|
|
882
955
|
// prepare the sockets for reading and writing
|
883
956
|
size_t i;
|
@@ -890,27 +963,28 @@ void EventMachine_t::_RunSelectOnce()
|
|
890
963
|
assert (sd != INVALID_SOCKET);
|
891
964
|
|
892
965
|
if (ed->SelectForRead())
|
893
|
-
|
966
|
+
rb_fd_set (sd, &(SelectData->fdreads));
|
894
967
|
if (ed->SelectForWrite())
|
895
|
-
|
968
|
+
rb_fd_set (sd, &(SelectData->fdwrites));
|
896
969
|
|
897
970
|
#ifdef OS_WIN32
|
898
971
|
/* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable.
|
899
972
|
Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html
|
900
973
|
*/
|
901
|
-
|
974
|
+
if (ed->IsConnectPending())
|
975
|
+
rb_fd_set (sd, &(SelectData->fderrors));
|
902
976
|
#endif
|
903
977
|
|
904
|
-
if (SelectData
|
905
|
-
SelectData
|
978
|
+
if (SelectData->maxsocket < sd)
|
979
|
+
SelectData->maxsocket = sd;
|
906
980
|
}
|
907
981
|
|
908
982
|
|
909
983
|
{ // read and write the sockets
|
910
984
|
//timeval tv = {1, 0}; // Solaris fails if the microseconds member is >= 1000000.
|
911
985
|
//timeval tv = Quantum;
|
912
|
-
SelectData
|
913
|
-
int s = SelectData
|
986
|
+
SelectData->tv = _TimeTilNextEvent();
|
987
|
+
int s = SelectData->_Select();
|
914
988
|
//rb_thread_blocking_region(xxx,(void*)&SelectData,RUBY_UBF_IO,0);
|
915
989
|
//int s = EmSelect (SelectData.maxsocket+1, &(SelectData.fdreads), &(SelectData.fdwrites), NULL, &(SelectData.tv));
|
916
990
|
//int s = SelectData.nSockets;
|
@@ -933,15 +1007,19 @@ void EventMachine_t::_RunSelectOnce()
|
|
933
1007
|
continue;
|
934
1008
|
assert (sd != INVALID_SOCKET);
|
935
1009
|
|
936
|
-
if (
|
937
|
-
|
938
|
-
|
1010
|
+
if (rb_fd_isset (sd, &(SelectData->fdwrites))) {
|
1011
|
+
// Double-check SelectForWrite() still returns true. If not, one of the callbacks must have
|
1012
|
+
// modified some value since we checked SelectForWrite() earlier in this method.
|
1013
|
+
if (ed->SelectForWrite())
|
1014
|
+
ed->Write();
|
1015
|
+
}
|
1016
|
+
if (rb_fd_isset (sd, &(SelectData->fdreads)))
|
939
1017
|
ed->Read();
|
940
|
-
if (
|
1018
|
+
if (rb_fd_isset (sd, &(SelectData->fderrors)))
|
941
1019
|
ed->HandleError();
|
942
1020
|
}
|
943
1021
|
|
944
|
-
if (
|
1022
|
+
if (rb_fd_isset (LoopBreakerReader, &(SelectData->fdreads)))
|
945
1023
|
_ReadLoopBreaker();
|
946
1024
|
}
|
947
1025
|
else if (s < 0) {
|
@@ -979,11 +1057,12 @@ void EventMachine_t::_CleanBadDescriptors()
|
|
979
1057
|
tv.tv_sec = 0;
|
980
1058
|
tv.tv_usec = 0;
|
981
1059
|
|
982
|
-
|
983
|
-
|
984
|
-
|
1060
|
+
rb_fdset_t fds;
|
1061
|
+
rb_fd_init(&fds);
|
1062
|
+
rb_fd_set(sd, &fds);
|
985
1063
|
|
986
|
-
int ret =
|
1064
|
+
int ret = rb_fd_select(sd + 1, &fds, NULL, NULL, &tv);
|
1065
|
+
rb_fd_term(&fds);
|
987
1066
|
|
988
1067
|
if (ret == -1) {
|
989
1068
|
if (errno == EBADF)
|
@@ -1600,6 +1679,16 @@ const unsigned long EventMachine_t::OpenDatagramSocket (const char *address, int
|
|
1600
1679
|
goto fail;
|
1601
1680
|
}
|
1602
1681
|
|
1682
|
+
// Set CLOEXEC. Only makes sense on Unix.
|
1683
|
+
{
|
1684
|
+
#ifdef OS_UNIX
|
1685
|
+
int cloexec = fcntl (sd, F_GETFD, 0);
|
1686
|
+
assert (cloexec >= 0);
|
1687
|
+
cloexec |= FD_CLOEXEC;
|
1688
|
+
fcntl (sd, F_SETFD, cloexec);
|
1689
|
+
#endif
|
1690
|
+
}
|
1691
|
+
|
1603
1692
|
if (bind (sd, (struct sockaddr*)&sin, sizeof(sin)) != 0)
|
1604
1693
|
goto fail;
|
1605
1694
|
|
@@ -1923,47 +2012,6 @@ const unsigned long EventMachine_t::AttachSD (int sd_accept)
|
|
1923
2012
|
}
|
1924
2013
|
|
1925
2014
|
|
1926
|
-
/*********************
|
1927
|
-
EventMachine_t::Popen
|
1928
|
-
*********************/
|
1929
|
-
#if OBSOLETE
|
1930
|
-
const char *EventMachine_t::Popen (const char *cmd, const char *mode)
|
1931
|
-
{
|
1932
|
-
#ifdef OS_WIN32
|
1933
|
-
throw std::runtime_error ("popen is currently unavailable on this platform");
|
1934
|
-
#endif
|
1935
|
-
|
1936
|
-
// The whole rest of this function is only compiled on Unix systems.
|
1937
|
-
// Eventually we need this functionality (or a full-duplex equivalent) on Windows.
|
1938
|
-
#ifdef OS_UNIX
|
1939
|
-
const char *output_binding = NULL;
|
1940
|
-
|
1941
|
-
FILE *fp = popen (cmd, mode);
|
1942
|
-
if (!fp)
|
1943
|
-
return NULL;
|
1944
|
-
|
1945
|
-
// From here, all early returns must pclose the stream.
|
1946
|
-
|
1947
|
-
// According to the pipe(2) manpage, descriptors returned from pipe have both
|
1948
|
-
// CLOEXEC and NONBLOCK clear. Do NOT set CLOEXEC. DO set nonblocking.
|
1949
|
-
if (!SetSocketNonblocking (fileno (fp))) {
|
1950
|
-
pclose (fp);
|
1951
|
-
return NULL;
|
1952
|
-
}
|
1953
|
-
|
1954
|
-
{ // Looking good.
|
1955
|
-
PipeDescriptor *pd = new PipeDescriptor (fp, this);
|
1956
|
-
if (!pd)
|
1957
|
-
throw std::runtime_error ("unable to allocate pipe");
|
1958
|
-
Add (pd);
|
1959
|
-
output_binding = pd->GetBinding();
|
1960
|
-
}
|
1961
|
-
|
1962
|
-
return output_binding;
|
1963
|
-
#endif
|
1964
|
-
}
|
1965
|
-
#endif // OBSOLETE
|
1966
|
-
|
1967
2015
|
/**************************
|
1968
2016
|
EventMachine_t::Socketpair
|
1969
2017
|
**************************/
|
@@ -2349,4 +2397,3 @@ int EventMachine_t::SetHeartbeatInterval(float interval)
|
|
2349
2397
|
return 0;
|
2350
2398
|
}
|
2351
2399
|
//#endif // OS_UNIX
|
2352
|
-
|