sensu-em 2.4.1-java → 2.5.0.beta-java
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.
- 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/lib/rubyeventmachine.jar +0 -0
- 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 +27 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cd81577274ffb873588073417aef55f93f6a76f
|
4
|
+
data.tar.gz: bdca94e3528cfd4790448a60c20a1398d696900b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 643200d1b2e606a478277ae4752fa3f73a240df8d7c077ff6c82160332d73a0d254a284f6c6d5d2e1dd5a8b32cde04eaf34ad5abc7912fb93d21b95bcf6be7ab
|
7
|
+
data.tar.gz: 2cd5177c480850136024b7bf6f455b4c1c065454b845ccdb8aa644d2bf82fc7c44a2223b1b02a9168e1bcb0b590f2c5f67eaf4087035254b614bef39bbd81079
|
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
|
-
|