eventmachine 1.0.4-java → 1.0.5-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +12 -1
- data/CHANGELOG.md +14 -0
- data/eventmachine.gemspec +1 -0
- data/ext/cmain.cpp +4 -2
- data/ext/ed.cpp +20 -7
- data/ext/em.cpp +68 -69
- data/ext/em.h +33 -10
- data/ext/extconf.rb +11 -1
- data/ext/fastfilereader/mapper.cpp +1 -1
- data/ext/project.h +11 -7
- data/ext/rubymain.cpp +6 -1
- data/ext/ssl.cpp +4 -1
- data/ext/ssl.h +4 -0
- data/lib/em/connection.rb +1 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +8 -3
- data/rakelib/package.rake +1 -1
- data/tests/test_attach.rb +1 -0
- data/tests/test_basic.rb +13 -16
- data/tests/test_connection_count.rb +1 -0
- data/tests/test_epoll.rb +11 -14
- 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_process_watch.rb +1 -0
- data/tests/test_processes.rb +7 -7
- data/tests/test_resolver.rb +30 -4
- data/tests/test_ssl_args.rb +2 -2
- data/tests/test_ssl_methods.rb +2 -5
- data/tests/test_ssl_verify.rb +60 -62
- data/tests/test_threaded_resource.rb +8 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 909d153b45cd30ecad7ef4f2b91009aa978b70eb
|
4
|
+
data.tar.gz: 493058213b19e7b4d32c51e72b15a54f2832d1e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 342e305aa3bd8792f115e6c7c1795f3fe482e11d92a1195b7346ff6c2d20c98b1c9462d0a26030d9e1d350682140a79db199c470b4b8fe6cca492b8e7059943d
|
7
|
+
data.tar.gz: 23c2852e6fcfd419eb5dec0ce005a515b7561cfe75b417d2f93d02817992fc4345b8cc3beff619adea9e7f80656de2180bdc24d5b56a5192293f1a1ebb329a5f
|
data/.travis.yml
CHANGED
@@ -1,5 +1,9 @@
|
|
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
|
5
9
|
- 1.9.3
|
@@ -8,3 +12,10 @@ rvm:
|
|
8
12
|
- 2.2
|
9
13
|
- rbx
|
10
14
|
- jruby
|
15
|
+
matrix:
|
16
|
+
allow_failures:
|
17
|
+
- rvm: rbx
|
18
|
+
- rvm: jruby
|
19
|
+
include:
|
20
|
+
- rvm: 2.0.0
|
21
|
+
os: osx
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.0.5 (February 2, 2015)
|
4
|
+
* use monotonic clocks on Linux, OS X, Solaris, and Windows [#563]
|
5
|
+
* use the rb_fd_* API to get autosized fd_sets [#502]
|
6
|
+
* add basic tests that the DNS resolver isn't leaking timers [#571]
|
7
|
+
* update to test-unit 2.x and improve various unit tests [#551]
|
8
|
+
* remove EventMachine_t::Popen code marked by ifdef OBSOLETE [#551]
|
9
|
+
* ruby 2.0 may fail at Queue.pop, so rescue and complain to $stderr [#551]
|
10
|
+
* set file handle to INVALID_HANDLE_VALUE after closing the file [#565]
|
11
|
+
* use `defined?` instead of rescuing NameError for flow control [#535]
|
12
|
+
* fix closing files and sockets on Windows [#564]
|
13
|
+
* fix file uploads in Windows [#562]
|
14
|
+
* catch failure to fork [#539]
|
15
|
+
* use chunks for SSL write [#545]
|
16
|
+
|
3
17
|
## 1.0.4 (December 19, 2014)
|
4
18
|
* add starttls_options to smtp server [#552]
|
5
19
|
* fix closesocket on windows [#497]
|
data/eventmachine.gemspec
CHANGED
@@ -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
@@ -762,8 +762,11 @@ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, c
|
|
762
762
|
|
763
763
|
ensure_eventmachine("evma_send_file_data_to_connection");
|
764
764
|
|
765
|
+
#if defined(OS_WIN32)
|
766
|
+
int Fd = open (filename, O_RDONLY|O_BINARY);
|
767
|
+
#else
|
765
768
|
int Fd = open (filename, O_RDONLY);
|
766
|
-
|
769
|
+
#endif
|
767
770
|
if (Fd < 0)
|
768
771
|
return errno;
|
769
772
|
// From here on, all early returns MUST close Fd.
|
@@ -785,7 +788,6 @@ extern "C" int evma_send_file_data_to_connection (const unsigned long binding, c
|
|
785
788
|
return -1;
|
786
789
|
}
|
787
790
|
|
788
|
-
|
789
791
|
r = read (Fd, data, filesize);
|
790
792
|
if (r != filesize) {
|
791
793
|
int e = errno;
|
data/ext/ed.cpp
CHANGED
@@ -566,11 +566,25 @@ int ConnectionDescriptor::SendOutboundData (const char *data, int length)
|
|
566
566
|
#ifdef WITH_SSL
|
567
567
|
if (SslBox) {
|
568
568
|
if (length > 0) {
|
569
|
-
int
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
569
|
+
int writed = 0;
|
570
|
+
char *p = (char*)data;
|
571
|
+
|
572
|
+
while (writed < length) {
|
573
|
+
int to_write = SSLBOX_INPUT_CHUNKSIZE;
|
574
|
+
int remaining = length - writed;
|
575
|
+
|
576
|
+
if (remaining < SSLBOX_INPUT_CHUNKSIZE)
|
577
|
+
to_write = remaining;
|
578
|
+
|
579
|
+
int w = SslBox->PutPlaintext (p, to_write);
|
580
|
+
if (w < 0) {
|
581
|
+
ScheduleClose (false);
|
582
|
+
}else
|
583
|
+
_DispatchCiphertext();
|
584
|
+
|
585
|
+
p += to_write;
|
586
|
+
writed += to_write;
|
587
|
+
}
|
574
588
|
}
|
575
589
|
// TODO: What's the correct return value?
|
576
590
|
return 1; // That's a wild guess, almost certainly wrong.
|
@@ -602,7 +616,6 @@ int ConnectionDescriptor::_SendRawOutboundData (const char *data, int length)
|
|
602
616
|
|
603
617
|
if (IsCloseScheduled())
|
604
618
|
return 0;
|
605
|
-
|
606
619
|
// 25Mar10: Ignore 0 length packets as they are not meaningful in TCP (as opposed to UDP)
|
607
620
|
// and can cause the assert(nbytes>0) to fail when OutboundPages has a bunch of 0 length pages.
|
608
621
|
if (length == 0)
|
@@ -1226,7 +1239,7 @@ void ConnectionDescriptor::_DispatchCiphertext()
|
|
1226
1239
|
assert (SslBox);
|
1227
1240
|
|
1228
1241
|
|
1229
|
-
char BigBuf [
|
1242
|
+
char BigBuf [SSLBOX_OUTPUT_CHUNKSIZE];
|
1230
1243
|
bool did_work;
|
1231
1244
|
|
1232
1245
|
do {
|
data/ext/em.cpp
CHANGED
@@ -85,6 +85,11 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
|
|
85
85
|
Quantum.tv_sec = 0;
|
86
86
|
Quantum.tv_usec = 90000;
|
87
87
|
|
88
|
+
/* Initialize monotonic timekeeping on OS X before the first call to GetRealTime */
|
89
|
+
#ifdef OS_DARWIN
|
90
|
+
(void) mach_timebase_info(&mach_timebase);
|
91
|
+
#endif
|
92
|
+
|
88
93
|
// Make sure the current loop time is sane, in case we do any initializations of
|
89
94
|
// objects before we start running.
|
90
95
|
_UpdateTime();
|
@@ -352,16 +357,49 @@ void EventMachine_t::_UpdateTime()
|
|
352
357
|
EventMachine_t::GetRealTime
|
353
358
|
***************************/
|
354
359
|
|
360
|
+
// Two great writeups of cross-platform monotonic time are at:
|
361
|
+
// http://www.python.org/dev/peps/pep-0418
|
362
|
+
// http://nadeausoftware.com/articles/2012/04/c_c_tip_how_measure_elapsed_real_time_benchmarking
|
363
|
+
// Uncomment the #pragma messages to confirm which compile-time option was used
|
355
364
|
uint64_t EventMachine_t::GetRealTime()
|
356
365
|
{
|
357
366
|
uint64_t current_time;
|
358
367
|
|
359
|
-
#if defined(
|
368
|
+
#if defined(HAVE_CONST_CLOCK_MONOTONIC_RAW)
|
369
|
+
// #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC_RAW"
|
370
|
+
// Linux 2.6.28 and above
|
371
|
+
struct timespec tv;
|
372
|
+
clock_gettime (CLOCK_MONOTONIC_RAW, &tv);
|
373
|
+
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000));
|
374
|
+
|
375
|
+
#elif defined(HAVE_CONST_CLOCK_MONOTONIC)
|
376
|
+
// #pragma message "GetRealTime: clock_gettime CLOCK_MONOTONIC"
|
377
|
+
// Linux, FreeBSD 5.0 and above, Solaris 8 and above, OpenBSD, NetBSD, DragonflyBSD
|
378
|
+
struct timespec tv;
|
379
|
+
clock_gettime (CLOCK_MONOTONIC, &tv);
|
380
|
+
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)((tv.tv_nsec)/1000));
|
381
|
+
|
382
|
+
#elif defined(HAVE_GETHRTIME)
|
383
|
+
// #pragma message "GetRealTime: gethrtime"
|
384
|
+
// Solaris and HP-UX
|
385
|
+
current_time = (uint64_t)gethrtime() / 1000;
|
386
|
+
|
387
|
+
#elif defined(OS_DARWIN)
|
388
|
+
// #pragma message "GetRealTime: mach_absolute_time"
|
389
|
+
// Mac OS X
|
390
|
+
// https://developer.apple.com/library/mac/qa/qa1398/_index.html
|
391
|
+
current_time = mach_absolute_time() * mach_timebase.numer / mach_timebase.denom / 1000;
|
392
|
+
|
393
|
+
#elif defined(OS_UNIX)
|
394
|
+
// #pragma message "GetRealTime: gettimeofday"
|
395
|
+
// Unix fallback
|
360
396
|
struct timeval tv;
|
361
397
|
gettimeofday (&tv, NULL);
|
362
398
|
current_time = (((uint64_t)(tv.tv_sec)) * 1000000LL) + ((uint64_t)(tv.tv_usec));
|
363
399
|
|
364
400
|
#elif defined(OS_WIN32)
|
401
|
+
// #pragma message "GetRealTime: GetTickCount"
|
402
|
+
// Future improvement: use GetTickCount64 in Windows Vista / Server 2008
|
365
403
|
unsigned tick = GetTickCount();
|
366
404
|
if (tick < LastTickCount)
|
367
405
|
TickCountTickover += 1;
|
@@ -370,6 +408,8 @@ uint64_t EventMachine_t::GetRealTime()
|
|
370
408
|
current_time *= 1000; // convert to microseconds
|
371
409
|
|
372
410
|
#else
|
411
|
+
// #pragma message "GetRealTime: time"
|
412
|
+
// Universal fallback
|
373
413
|
current_time = (uint64_t)time(NULL) * 1000000LL;
|
374
414
|
#endif
|
375
415
|
|
@@ -536,12 +576,12 @@ void EventMachine_t::_RunEpollOnce()
|
|
536
576
|
#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
|
537
577
|
if ((ret = rb_wait_for_single_fd(epfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
|
538
578
|
#else
|
539
|
-
|
579
|
+
rb_fdset_t fdreads;
|
540
580
|
|
541
|
-
|
542
|
-
|
581
|
+
rb_fd_init(&fdreads);
|
582
|
+
rb_fd_set(epfd, &fdreads);
|
543
583
|
|
544
|
-
if ((ret =
|
584
|
+
if ((ret = rb_thread_fd_select(epfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
|
545
585
|
#endif
|
546
586
|
if (ret == -1) {
|
547
587
|
assert(errno != EINVAL);
|
@@ -613,12 +653,12 @@ void EventMachine_t::_RunKqueueOnce()
|
|
613
653
|
#ifdef HAVE_RB_WAIT_FOR_SINGLE_FD
|
614
654
|
if ((ret = rb_wait_for_single_fd(kqfd, RB_WAITFD_IN|RB_WAITFD_PRI, &tv)) < 1) {
|
615
655
|
#else
|
616
|
-
|
656
|
+
rb_fdset_t fdreads;
|
617
657
|
|
618
|
-
|
619
|
-
|
658
|
+
rb_fd_init(&fdreads);
|
659
|
+
rb_fd_set(kqfd, &fdreads);
|
620
660
|
|
621
|
-
if ((ret =
|
661
|
+
if ((ret = rb_thread_fd_select(kqfd + 1, &fdreads, NULL, NULL, &tv)) < 1) {
|
622
662
|
#endif
|
623
663
|
if (ret == -1) {
|
624
664
|
assert(errno != EINVAL);
|
@@ -806,9 +846,9 @@ SelectData_t::SelectData_t
|
|
806
846
|
SelectData_t::SelectData_t()
|
807
847
|
{
|
808
848
|
maxsocket = 0;
|
809
|
-
|
810
|
-
|
811
|
-
|
849
|
+
rb_fd_init (&fdreads);
|
850
|
+
rb_fd_init (&fdwrites);
|
851
|
+
rb_fd_init (&fderrors);
|
812
852
|
}
|
813
853
|
|
814
854
|
|
@@ -821,7 +861,7 @@ _SelectDataSelect
|
|
821
861
|
static VALUE _SelectDataSelect (void *v)
|
822
862
|
{
|
823
863
|
SelectData_t *sd = (SelectData_t*)v;
|
824
|
-
sd->nSockets =
|
864
|
+
sd->nSockets = rb_fd_select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), &(sd->fderrors), &(sd->tv));
|
825
865
|
return Qnil;
|
826
866
|
}
|
827
867
|
#endif
|
@@ -863,9 +903,9 @@ void EventMachine_t::_RunSelectOnce()
|
|
863
903
|
|
864
904
|
SelectData_t SelectData;
|
865
905
|
/*
|
866
|
-
|
867
|
-
|
868
|
-
|
906
|
+
rb_fdset_t fdreads, fdwrites;
|
907
|
+
rb_fd_init (&fdreads);
|
908
|
+
rb_fd_init (&fdwrites);
|
869
909
|
|
870
910
|
int maxsocket = 0;
|
871
911
|
*/
|
@@ -875,7 +915,7 @@ void EventMachine_t::_RunSelectOnce()
|
|
875
915
|
// running on localhost with a randomly-chosen port. (*Puke*)
|
876
916
|
// Windows has a version of the Unix pipe() library function, but it doesn't
|
877
917
|
// give you back descriptors that are selectable.
|
878
|
-
|
918
|
+
rb_fd_set (LoopBreakerReader, &(SelectData.fdreads));
|
879
919
|
if (SelectData.maxsocket < LoopBreakerReader)
|
880
920
|
SelectData.maxsocket = LoopBreakerReader;
|
881
921
|
|
@@ -890,15 +930,15 @@ void EventMachine_t::_RunSelectOnce()
|
|
890
930
|
assert (sd != INVALID_SOCKET);
|
891
931
|
|
892
932
|
if (ed->SelectForRead())
|
893
|
-
|
933
|
+
rb_fd_set (sd, &(SelectData.fdreads));
|
894
934
|
if (ed->SelectForWrite())
|
895
|
-
|
935
|
+
rb_fd_set (sd, &(SelectData.fdwrites));
|
896
936
|
|
897
937
|
#ifdef OS_WIN32
|
898
938
|
/* 21Sep09: on windows, a non-blocking connect() that fails does not come up as writable.
|
899
939
|
Instead, it is added to the error set. See http://www.mail-archive.com/openssl-users@openssl.org/msg58500.html
|
900
940
|
*/
|
901
|
-
|
941
|
+
rb_fd_set (sd, &(SelectData.fderrors));
|
902
942
|
#endif
|
903
943
|
|
904
944
|
if (SelectData.maxsocket < sd)
|
@@ -933,15 +973,15 @@ void EventMachine_t::_RunSelectOnce()
|
|
933
973
|
continue;
|
934
974
|
assert (sd != INVALID_SOCKET);
|
935
975
|
|
936
|
-
if (
|
976
|
+
if (rb_fd_isset (sd, &(SelectData.fdwrites)))
|
937
977
|
ed->Write();
|
938
|
-
if (
|
978
|
+
if (rb_fd_isset (sd, &(SelectData.fdreads)))
|
939
979
|
ed->Read();
|
940
|
-
if (
|
980
|
+
if (rb_fd_isset (sd, &(SelectData.fderrors)))
|
941
981
|
ed->HandleError();
|
942
982
|
}
|
943
983
|
|
944
|
-
if (
|
984
|
+
if (rb_fd_isset (LoopBreakerReader, &(SelectData.fdreads)))
|
945
985
|
_ReadLoopBreaker();
|
946
986
|
}
|
947
987
|
else if (s < 0) {
|
@@ -979,11 +1019,11 @@ void EventMachine_t::_CleanBadDescriptors()
|
|
979
1019
|
tv.tv_sec = 0;
|
980
1020
|
tv.tv_usec = 0;
|
981
1021
|
|
982
|
-
|
983
|
-
|
984
|
-
|
1022
|
+
rb_fdset_t fds;
|
1023
|
+
rb_fd_init(&fds);
|
1024
|
+
rb_fd_set(sd, &fds);
|
985
1025
|
|
986
|
-
int ret =
|
1026
|
+
int ret = rb_fd_select(sd + 1, &fds, NULL, NULL, &tv);
|
987
1027
|
|
988
1028
|
if (ret == -1) {
|
989
1029
|
if (errno == EBADF)
|
@@ -1923,47 +1963,6 @@ const unsigned long EventMachine_t::AttachSD (int sd_accept)
|
|
1923
1963
|
}
|
1924
1964
|
|
1925
1965
|
|
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
1966
|
/**************************
|
1968
1967
|
EventMachine_t::Socketpair
|
1969
1968
|
**************************/
|
data/ext/em.h
CHANGED
@@ -22,12 +22,7 @@ See the file COPYING for complete licensing information.
|
|
22
22
|
|
23
23
|
#ifdef BUILD_FOR_RUBY
|
24
24
|
#include <ruby.h>
|
25
|
-
|
26
|
-
#ifdef HAVE_RB_THREAD_FD_SELECT
|
27
|
-
#define EmSelect rb_thread_fd_select
|
28
|
-
#else
|
29
|
-
#define EmSelect rb_thread_select
|
30
|
-
#endif
|
25
|
+
#define EmSelect rb_thread_fd_select
|
31
26
|
|
32
27
|
#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
|
33
28
|
#include <ruby/thread.h>
|
@@ -66,7 +61,31 @@ See the file COPYING for complete licensing information.
|
|
66
61
|
#define RSTRING_LENINT(str) RSTRING_LEN(str)
|
67
62
|
#endif
|
68
63
|
#else
|
69
|
-
#define EmSelect
|
64
|
+
#define EmSelect rb_fd_select
|
65
|
+
#endif
|
66
|
+
|
67
|
+
#ifndef rb_fd_max
|
68
|
+
#define fd_check(n) (((n) < FD_SETSIZE) ? 1 : 0*fprintf(stderr, "fd %d too large for select\n", (n)))
|
69
|
+
// These definitions are cribbed from include/ruby/intern.h in Ruby 1.9.3,
|
70
|
+
// with this change: any macros that read or write the nth element of an
|
71
|
+
// fdset first call fd_check to make sure n is in bounds.
|
72
|
+
typedef fd_set rb_fdset_t;
|
73
|
+
#define rb_fd_zero(f) FD_ZERO(f)
|
74
|
+
#define rb_fd_set(n, f) do { if (fd_check(n)) FD_SET((n), (f)); } while(0)
|
75
|
+
#define rb_fd_clr(n, f) do { if (fd_check(n)) FD_CLR((n), (f)); } while(0)
|
76
|
+
#define rb_fd_isset(n, f) (fd_check(n) ? FD_ISSET((n), (f)) : 0)
|
77
|
+
#define rb_fd_copy(d, s, n) (*(d) = *(s))
|
78
|
+
#define rb_fd_dup(d, s) (*(d) = *(s))
|
79
|
+
#define rb_fd_resize(n, f) ((void)(f))
|
80
|
+
#define rb_fd_ptr(f) (f)
|
81
|
+
#define rb_fd_init(f) FD_ZERO(f)
|
82
|
+
#define rb_fd_init_copy(d, s) (*(d) = *(s))
|
83
|
+
#define rb_fd_term(f) ((void)(f))
|
84
|
+
#define rb_fd_max(f) FD_SETSIZE
|
85
|
+
#define rb_fd_select(n, rfds, wfds, efds, timeout) \
|
86
|
+
select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout))
|
87
|
+
#define rb_thread_fd_select(n, rfds, wfds, efds, timeout) \
|
88
|
+
rb_thread_select(fd_check((n)-1) ? (n) : FD_SETSIZE, (rfds), (wfds), (efds), (timeout))
|
70
89
|
#endif
|
71
90
|
|
72
91
|
class EventableDescriptor;
|
@@ -213,6 +232,10 @@ class EventMachine_t
|
|
213
232
|
unsigned LastTickCount;
|
214
233
|
#endif
|
215
234
|
|
235
|
+
#ifdef OS_DARWIN
|
236
|
+
mach_timebase_info_data_t mach_timebase;
|
237
|
+
#endif
|
238
|
+
|
216
239
|
private:
|
217
240
|
bool bTerminateSignalReceived;
|
218
241
|
|
@@ -243,9 +266,9 @@ struct SelectData_t
|
|
243
266
|
int _Select();
|
244
267
|
|
245
268
|
int maxsocket;
|
246
|
-
|
247
|
-
|
248
|
-
|
269
|
+
rb_fdset_t fdreads;
|
270
|
+
rb_fdset_t fdwrites;
|
271
|
+
rb_fdset_t fderrors;
|
249
272
|
timeval tv;
|
250
273
|
int nSockets;
|
251
274
|
};
|
data/ext/extconf.rb
CHANGED
@@ -42,7 +42,7 @@ end
|
|
42
42
|
if ENV['CROSS_COMPILING']
|
43
43
|
openssl_version = ENV.fetch("OPENSSL_VERSION", "1.0.1i")
|
44
44
|
openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-#{openssl_version}/")
|
45
|
-
if File.
|
45
|
+
if File.exist?(openssl_dir)
|
46
46
|
FileUtils.mkdir_p Dir.pwd+"/openssl/"
|
47
47
|
FileUtils.cp Dir[openssl_dir+"/include/openssl/*.h"], Dir.pwd+"/openssl/", :verbose => true
|
48
48
|
FileUtils.cp Dir[openssl_dir+"/lib*.a"], Dir.pwd, :verbose => true
|
@@ -139,6 +139,8 @@ when /openbsd/
|
|
139
139
|
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
|
140
140
|
|
141
141
|
when /darwin/
|
142
|
+
add_define 'OS_DARWIN'
|
143
|
+
|
142
144
|
# on Unix we need a g++ link, not gcc.
|
143
145
|
# Ff line contributed by Daniel Harple.
|
144
146
|
CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
|
@@ -166,6 +168,14 @@ else
|
|
166
168
|
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
167
169
|
end
|
168
170
|
|
171
|
+
# Platform-specific time functions
|
172
|
+
if have_func('clock_gettime')
|
173
|
+
# clock_gettime is POSIX, but the monotonic clocks are not
|
174
|
+
have_const('CLOCK_MONOTONIC_RAW', 'time.h') # Linux
|
175
|
+
have_const('CLOCK_MONOTONIC', 'time.h') # Linux, Solaris, BSDs
|
176
|
+
else
|
177
|
+
have_func('gethrtime') # Older Solaris and HP-UX
|
178
|
+
end
|
169
179
|
|
170
180
|
# solaris c++ compiler doesn't have make_pair()
|
171
181
|
TRY_LINK.sub!('$(CC)', '$(CXX)')
|
data/ext/project.h
CHANGED
@@ -78,6 +78,11 @@ typedef int SOCKET;
|
|
78
78
|
#endif
|
79
79
|
#endif /* _AIX */
|
80
80
|
|
81
|
+
#ifdef OS_DARWIN
|
82
|
+
#include <mach/mach.h>
|
83
|
+
#include <mach/mach_time.h>
|
84
|
+
#endif /* OS_DARWIN */
|
85
|
+
|
81
86
|
#endif /* OS_UNIX */
|
82
87
|
|
83
88
|
#ifdef OS_WIN32
|
@@ -85,7 +90,9 @@ typedef int SOCKET;
|
|
85
90
|
// 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
|
86
91
|
//#define FD_SETSIZE 1024
|
87
92
|
|
93
|
+
// WIN32_LEAN_AND_MEAN excludes APIs such as Cryptography, DDE, RPC, Shell, and Windows Sockets.
|
88
94
|
#define WIN32_LEAN_AND_MEAN
|
95
|
+
|
89
96
|
#include <windows.h>
|
90
97
|
#include <winsock2.h>
|
91
98
|
#include <ws2tcpip.h>
|
@@ -93,13 +100,10 @@ typedef int SOCKET;
|
|
93
100
|
#include <fcntl.h>
|
94
101
|
#include <assert.h>
|
95
102
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
#
|
100
|
-
#define _PID_T_
|
101
|
-
typedef int pid_t;
|
102
|
-
#endif /* _PID_T_ */
|
103
|
+
// Use the Win32 wrapper library that Ruby owns to be able to close sockets with the close() function
|
104
|
+
#define RUBY_EXPORT
|
105
|
+
#include <ruby/defines.h>
|
106
|
+
#include <ruby/win32.h>
|
103
107
|
#endif /* OS_WIN32 */
|
104
108
|
|
105
109
|
#if !defined(_MSC_VER) || _MSC_VER > 1500
|
data/ext/rubymain.cpp
CHANGED
@@ -833,7 +833,12 @@ static VALUE t_invoke_popen (VALUE self, VALUE cmd)
|
|
833
833
|
}
|
834
834
|
strings[len] = NULL;
|
835
835
|
|
836
|
-
|
836
|
+
unsigned long f = 0;
|
837
|
+
try {
|
838
|
+
f = evma_popen (strings);
|
839
|
+
} catch (std::runtime_error e) {
|
840
|
+
f = 0; // raise exception below
|
841
|
+
}
|
837
842
|
if (!f) {
|
838
843
|
char *err = strerror (errno);
|
839
844
|
char buf[100];
|
data/ext/ssl.cpp
CHANGED
@@ -392,13 +392,16 @@ int SslBox_t::PutPlaintext (const char *buf, int bufsize)
|
|
392
392
|
|
393
393
|
bool fatal = false;
|
394
394
|
bool did_work = false;
|
395
|
+
int pending = BIO_pending(pbioWrite);
|
395
396
|
|
396
|
-
while (OutboundQ.HasPages()) {
|
397
|
+
while (OutboundQ.HasPages() && pending < SSLBOX_WRITE_BUFFER_SIZE) {
|
397
398
|
const char *page;
|
398
399
|
int length;
|
399
400
|
OutboundQ.Front (&page, &length);
|
400
401
|
assert (page && (length > 0));
|
401
402
|
int n = SSL_write (pSSL, page, length);
|
403
|
+
pending = BIO_pending(pbioWrite);
|
404
|
+
|
402
405
|
if (n > 0) {
|
403
406
|
did_work = true;
|
404
407
|
OutboundQ.PopFront();
|
data/ext/ssl.h
CHANGED
data/lib/em/connection.rb
CHANGED
@@ -409,7 +409,7 @@ module EventMachine
|
|
409
409
|
[priv_key, cert_chain].each do |file|
|
410
410
|
next if file.nil? or file.empty?
|
411
411
|
raise FileNotFoundException,
|
412
|
-
"Could not find #{file} for start_tls" unless File.
|
412
|
+
"Could not find #{file} for start_tls" unless File.exist? file
|
413
413
|
end
|
414
414
|
|
415
415
|
EventMachine::set_tls_parms(@signature, priv_key || '', cert_chain || '', verify_peer)
|
data/lib/em/version.rb
CHANGED
data/lib/eventmachine.rb
CHANGED
@@ -1042,7 +1042,12 @@ module EventMachine
|
|
1042
1042
|
thread = Thread.new do
|
1043
1043
|
Thread.current.abort_on_exception = true
|
1044
1044
|
while true
|
1045
|
-
|
1045
|
+
begin
|
1046
|
+
op, cback = *@threadqueue.pop
|
1047
|
+
rescue ThreadError
|
1048
|
+
$stderr.puts $!.message
|
1049
|
+
break # Ruby 2.0 may fail at Queue.pop
|
1050
|
+
end
|
1046
1051
|
result = op.call
|
1047
1052
|
@resultqueue << [result, cback]
|
1048
1053
|
EventMachine.signal_loopbreak
|
@@ -1521,9 +1526,9 @@ module EventMachine
|
|
1521
1526
|
raise ArgumentError, "must provide module or subclass of #{klass.name}" unless klass >= handler
|
1522
1527
|
handler
|
1523
1528
|
elsif handler
|
1524
|
-
|
1529
|
+
if defined?(handler::EM_CONNECTION_CLASS)
|
1525
1530
|
handler::EM_CONNECTION_CLASS
|
1526
|
-
|
1531
|
+
else
|
1527
1532
|
handler::const_set(:EM_CONNECTION_CLASS, Class.new(klass) {include handler})
|
1528
1533
|
end
|
1529
1534
|
else
|
data/rakelib/package.rake
CHANGED
data/tests/test_attach.rb
CHANGED
data/tests/test_basic.rb
CHANGED
@@ -179,18 +179,15 @@ class TestBasic < Test::Unit::TestCase
|
|
179
179
|
assert x
|
180
180
|
end
|
181
181
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
end
|
192
|
-
else
|
193
|
-
warn "EM.set_heartbeat_interval not implemented, skipping a test in #{__FILE__}"
|
182
|
+
def test_set_heartbeat_interval
|
183
|
+
omit_if(jruby?)
|
184
|
+
interval = 0.5
|
185
|
+
EM.run {
|
186
|
+
EM.set_heartbeat_interval interval
|
187
|
+
$interval = EM.get_heartbeat_interval
|
188
|
+
EM.stop
|
189
|
+
}
|
190
|
+
assert_equal(interval, $interval)
|
194
191
|
end
|
195
192
|
|
196
193
|
module PostInitRaiser
|
@@ -226,6 +223,7 @@ class TestBasic < Test::Unit::TestCase
|
|
226
223
|
end
|
227
224
|
|
228
225
|
def test_schedule_close
|
226
|
+
omit_if(jruby?)
|
229
227
|
localhost, port = '127.0.0.1', 9000
|
230
228
|
timer_ran = false
|
231
229
|
num_close_scheduled = nil
|
@@ -247,22 +245,21 @@ class TestBasic < Test::Unit::TestCase
|
|
247
245
|
end
|
248
246
|
|
249
247
|
def test_fork_safe
|
250
|
-
|
248
|
+
omit_if(jruby?)
|
251
249
|
|
252
250
|
read, write = IO.pipe
|
253
251
|
EM.run do
|
254
|
-
|
252
|
+
fork do
|
255
253
|
write.puts "forked"
|
256
254
|
EM.run do
|
257
255
|
EM.next_tick do
|
258
256
|
write.puts "EM ran"
|
259
|
-
|
257
|
+
EM.stop
|
260
258
|
end
|
261
259
|
end
|
262
260
|
end
|
263
261
|
EM.stop
|
264
262
|
end
|
265
|
-
Process.waitall
|
266
263
|
assert_equal "forked\n", read.readline
|
267
264
|
assert_equal "EM ran\n", read.readline
|
268
265
|
ensure
|
data/tests/test_epoll.rb
CHANGED
@@ -25,19 +25,16 @@ class TestEpoll < Test::Unit::TestCase
|
|
25
25
|
end
|
26
26
|
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
a = EM.set_descriptor_table_size( 1024 )
|
39
|
-
assert( a == 1024 )
|
40
|
-
end
|
28
|
+
# We can set the rlimit/nofile of a process but we can only set it
|
29
|
+
# higher if we're running as root.
|
30
|
+
# On most systems, the default value is 1024.
|
31
|
+
def test_rlimit
|
32
|
+
omit_if(windows? || jruby?)
|
33
|
+
unless EM.set_descriptor_table_size >= 1024
|
34
|
+
a = EM.set_descriptor_table_size
|
35
|
+
assert( a <= 1024 )
|
36
|
+
a = EM.set_descriptor_table_size( 1024 )
|
37
|
+
assert( a == 1024 )
|
41
38
|
end
|
42
39
|
end
|
43
40
|
|
@@ -97,7 +94,7 @@ class TestEpoll < Test::Unit::TestCase
|
|
97
94
|
assert_equal( "abcdefghij", $out )
|
98
95
|
end
|
99
96
|
|
100
|
-
# XXX this test fails randomly
|
97
|
+
# XXX this test fails randomly...
|
101
98
|
def _test_unix_domain
|
102
99
|
fn = "/tmp/xxx.chain"
|
103
100
|
EM.epoll
|
data/tests/test_iterator.rb
CHANGED
@@ -18,7 +18,7 @@ class TestIterator < Test::Unit::TestCase
|
|
18
18
|
}, proc {EM.stop})
|
19
19
|
}
|
20
20
|
assert_equal(10, items.keys.size)
|
21
|
-
assert_equal(
|
21
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_concurrency_bigger_than_list_size
|
@@ -33,7 +33,7 @@ class TestIterator < Test::Unit::TestCase
|
|
33
33
|
}, proc {EM.stop})
|
34
34
|
}
|
35
35
|
assert_equal(1, items.keys.size)
|
36
|
-
assert_equal(
|
36
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
37
37
|
end
|
38
38
|
|
39
39
|
|
@@ -56,7 +56,7 @@ class TestIterator < Test::Unit::TestCase
|
|
56
56
|
}
|
57
57
|
}
|
58
58
|
assert_equal(9, items.keys.size)
|
59
|
-
assert_equal(
|
59
|
+
assert_equal(list.to_a.sort, items.values.flatten.sort)
|
60
60
|
end
|
61
61
|
|
62
62
|
def test_map
|
@@ -65,7 +65,7 @@ class TestIterator < Test::Unit::TestCase
|
|
65
65
|
EM::Iterator.new(list).map(proc{ |num,iter|
|
66
66
|
EM.add_timer(0.01){ iter.return(num) }
|
67
67
|
}, proc{ |results|
|
68
|
-
assert_equal(
|
68
|
+
assert_equal(list.to_a.size, results.size)
|
69
69
|
EM.stop
|
70
70
|
})
|
71
71
|
}
|
@@ -80,7 +80,7 @@ class TestIterator < Test::Unit::TestCase
|
|
80
80
|
iter.return(hash)
|
81
81
|
}
|
82
82
|
}, proc{ |results|
|
83
|
-
assert_equal(results.keys, list)
|
83
|
+
assert_equal(results.keys.sort, list.sort)
|
84
84
|
EM.stop
|
85
85
|
})
|
86
86
|
}
|
@@ -94,4 +94,4 @@ class TestIterator < Test::Unit::TestCase
|
|
94
94
|
EM.stop
|
95
95
|
}
|
96
96
|
end
|
97
|
-
end
|
97
|
+
end
|
data/tests/test_kb.rb
CHANGED
@@ -2,33 +2,27 @@ require 'em_test_helper'
|
|
2
2
|
|
3
3
|
class TestKeyboardEvents < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
EM::stop if d == "STOP"
|
10
|
-
end
|
5
|
+
module KbHandler
|
6
|
+
include EM::Protocols::LineText2
|
7
|
+
def receive_line d
|
8
|
+
EM::stop if d == "STOP"
|
11
9
|
end
|
10
|
+
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
else
|
27
|
-
warn "EM.open_keyboard not implemented, skipping tests in #{__FILE__}"
|
28
|
-
|
29
|
-
# Because some rubies will complain if a TestCase class has no tests
|
30
|
-
def test_em_open_keyboard_unsupported
|
31
|
-
assert true
|
12
|
+
# This test doesn't actually do anything useful but is here to
|
13
|
+
# illustrate the usage. If you removed the timer and ran this test
|
14
|
+
# by itself on a console, and then typed into the console, it would
|
15
|
+
# work.
|
16
|
+
# I don't know how to get the test harness to simulate actual keystrokes.
|
17
|
+
# When someone figures that out, then we can make this a real test.
|
18
|
+
#
|
19
|
+
def test_kb
|
20
|
+
omit_if(jruby?)
|
21
|
+
omit_if(!$stdout.tty?) # don't run the test unless it stands a chance of validity.
|
22
|
+
EM.run do
|
23
|
+
EM.open_keyboard KbHandler
|
24
|
+
EM::Timer.new(1) { EM.stop }
|
32
25
|
end
|
33
26
|
end
|
27
|
+
|
34
28
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'em_test_helper'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
class TestManyFDs < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@port = next_port
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_connection_class_cache
|
10
|
+
mod = Module.new
|
11
|
+
a = nil
|
12
|
+
Process.setrlimit(Process::RLIMIT_NOFILE,4096);
|
13
|
+
EM.run {
|
14
|
+
EM.start_server '127.0.0.1', @port, mod
|
15
|
+
1100.times do
|
16
|
+
a = EM.connect '127.0.0.1', @port, mod
|
17
|
+
assert_kind_of EM::Connection, a
|
18
|
+
end
|
19
|
+
EM.stop
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
data/tests/test_process_watch.rb
CHANGED
data/tests/test_processes.rb
CHANGED
@@ -37,8 +37,8 @@ class TestProcesses < Test::Unit::TestCase
|
|
37
37
|
}
|
38
38
|
|
39
39
|
assert( $out.length > 0 )
|
40
|
-
assert_equal($status.exitstatus
|
41
|
-
|
40
|
+
assert_equal(0, $status.exitstatus)
|
41
|
+
assert_kind_of(Process::Status, $status)
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_em_system_pid
|
@@ -57,8 +57,8 @@ class TestProcesses < Test::Unit::TestCase
|
|
57
57
|
}
|
58
58
|
|
59
59
|
assert( $out.length > 0 )
|
60
|
-
assert_equal($status.exitstatus
|
61
|
-
|
60
|
+
assert_equal(0, $status.exitstatus)
|
61
|
+
assert_kind_of(Process::Status, $status)
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_em_system_with_two_procs
|
@@ -111,9 +111,9 @@ class TestProcesses < Test::Unit::TestCase
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
EM.run
|
115
|
-
EM.popen('
|
116
|
-
|
114
|
+
EM.run do
|
115
|
+
EM.popen('echo 1', test_client)
|
116
|
+
end
|
117
117
|
|
118
118
|
assert_equal 1, c_rx
|
119
119
|
end
|
data/tests/test_resolver.rb
CHANGED
@@ -33,7 +33,7 @@ class TestResolver < Test::Unit::TestCase
|
|
33
33
|
d = EM::DNS::Resolver.resolve "google.com"
|
34
34
|
d.errback { assert false }
|
35
35
|
d.callback { |r|
|
36
|
-
|
36
|
+
assert_kind_of(Array, r)
|
37
37
|
assert r.size > 1
|
38
38
|
EM.stop
|
39
39
|
}
|
@@ -45,11 +45,37 @@ class TestResolver < Test::Unit::TestCase
|
|
45
45
|
d = EM::DNS::Resolver.resolve "localhost"
|
46
46
|
d.errback { assert false }
|
47
47
|
d.callback { |r|
|
48
|
-
|
49
|
-
|
48
|
+
assert_include(["127.0.0.1", "::1"], r.first)
|
49
|
+
assert_kind_of(Array, r)
|
50
50
|
|
51
51
|
EM.stop
|
52
52
|
}
|
53
53
|
}
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
|
+
def test_timer_cleanup
|
57
|
+
EM.run {
|
58
|
+
d = EM::DNS::Resolver.resolve "google.com"
|
59
|
+
d.errback { assert false }
|
60
|
+
d.callback { |r|
|
61
|
+
# This isn't a great test, but it's hard to get more canonical
|
62
|
+
# confirmation that the timer is cancelled
|
63
|
+
assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer))
|
64
|
+
|
65
|
+
EM.stop
|
66
|
+
}
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_failure_timer_cleanup
|
71
|
+
EM.run {
|
72
|
+
d = EM::DNS::Resolver.resolve "asdfasdf"
|
73
|
+
d.callback { assert false }
|
74
|
+
d.errback {
|
75
|
+
assert_nil(EM::DNS::Resolver.socket.instance_variable_get(:@timer))
|
76
|
+
|
77
|
+
EM.stop
|
78
|
+
}
|
79
|
+
}
|
80
|
+
end
|
81
|
+
end
|
data/tests/test_ssl_args.rb
CHANGED
@@ -45,7 +45,7 @@ class TestSslArgs < Test::Unit::TestCase
|
|
45
45
|
def test_tls_params_file_doesnt_exist
|
46
46
|
priv_file, cert_file = 'foo_priv_key', 'bar_cert_file'
|
47
47
|
[priv_file, cert_file].all? do |f|
|
48
|
-
assert(!File.
|
48
|
+
assert(!File.exist?(f), "Cert file #{f} seems to exist, and should not for the tests")
|
49
49
|
end
|
50
50
|
|
51
51
|
# associate_callback_target is a pain! (build!)
|
@@ -75,4 +75,4 @@ class TestSslArgs < Test::Unit::TestCase
|
|
75
75
|
assert(false, 'should not have raised an exception')
|
76
76
|
end
|
77
77
|
end
|
78
|
-
end if EM.ssl?
|
78
|
+
end if EM.ssl?
|
data/tests/test_ssl_methods.rb
CHANGED
@@ -3,7 +3,6 @@ require 'em_test_helper'
|
|
3
3
|
class TestSSLMethods < Test::Unit::TestCase
|
4
4
|
|
5
5
|
module ServerHandler
|
6
|
-
|
7
6
|
def post_init
|
8
7
|
start_tls
|
9
8
|
end
|
@@ -12,11 +11,9 @@ class TestSSLMethods < Test::Unit::TestCase
|
|
12
11
|
$server_called_back = true
|
13
12
|
$server_cert_value = get_peer_cert
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
15
|
|
18
16
|
module ClientHandler
|
19
|
-
|
20
17
|
def post_init
|
21
18
|
start_tls
|
22
19
|
end
|
@@ -26,10 +23,10 @@ class TestSSLMethods < Test::Unit::TestCase
|
|
26
23
|
$client_cert_value = get_peer_cert
|
27
24
|
EM.stop_event_loop
|
28
25
|
end
|
29
|
-
|
30
26
|
end
|
31
27
|
|
32
28
|
def test_ssl_methods
|
29
|
+
omit_unless(EM.ssl?)
|
33
30
|
$server_called_back, $client_called_back = false, false
|
34
31
|
$server_cert_value, $client_cert_value = nil, nil
|
35
32
|
|
@@ -45,4 +42,4 @@ class TestSSLMethods < Test::Unit::TestCase
|
|
45
42
|
assert($client_cert_value.is_a?(String))
|
46
43
|
end
|
47
44
|
|
48
|
-
end
|
45
|
+
end
|
data/tests/test_ssl_verify.rb
CHANGED
@@ -1,82 +1,80 @@
|
|
1
1
|
require 'em_test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class TestSslVerify < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
$dir = File.dirname(File.expand_path(__FILE__)) + '/'
|
6
|
+
$cert_from_file = File.read($dir+'client.crt')
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
module Client
|
10
|
+
def connection_completed
|
11
|
+
start_tls(:private_key_file => $dir+'client.key', :cert_chain_file => $dir+'client.crt')
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def ssl_handshake_completed
|
15
|
+
$client_handshake_completed = true
|
16
|
+
close_connection
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
19
|
+
def unbind
|
20
|
+
EM.stop_event_loop
|
23
21
|
end
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
module AcceptServer
|
25
|
+
def post_init
|
26
|
+
start_tls(:verify_peer => true)
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
def ssl_verify_peer(cert)
|
30
|
+
$cert_from_server = cert
|
31
|
+
true
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
end
|
34
|
+
def ssl_handshake_completed
|
35
|
+
$server_handshake_completed = true
|
38
36
|
end
|
37
|
+
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
module DenyServer
|
40
|
+
def post_init
|
41
|
+
start_tls(:verify_peer => true)
|
42
|
+
end
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
44
|
+
def ssl_verify_peer(cert)
|
45
|
+
$cert_from_server = cert
|
46
|
+
# Do not accept the peer. This should now cause the connection to shut down without the SSL handshake being completed.
|
47
|
+
false
|
48
|
+
end
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
end
|
50
|
+
def ssl_handshake_completed
|
51
|
+
$server_handshake_completed = true
|
54
52
|
end
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
55
|
+
def test_accept_server
|
56
|
+
omit_unless(EM.ssl?)
|
57
|
+
$client_handshake_completed, $server_handshake_completed = false, false
|
58
|
+
EM.run {
|
59
|
+
EM.start_server("127.0.0.1", 16784, AcceptServer)
|
60
|
+
EM.connect("127.0.0.1", 16784, Client).instance_variable_get("@signature")
|
61
|
+
}
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
assert_equal($cert_from_file, $cert_from_server)
|
64
|
+
assert($client_handshake_completed)
|
65
|
+
assert($server_handshake_completed)
|
66
|
+
end
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
68
|
+
def test_deny_server
|
69
|
+
omit_unless(EM.ssl?)
|
70
|
+
$client_handshake_completed, $server_handshake_completed = false, false
|
71
|
+
EM.run {
|
72
|
+
EM.start_server("127.0.0.1", 16784, DenyServer)
|
73
|
+
EM.connect("127.0.0.1", 16784, Client)
|
74
|
+
}
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
76
|
+
assert_equal($cert_from_file, $cert_from_server)
|
77
|
+
assert(!$client_handshake_completed)
|
78
|
+
assert(!$server_handshake_completed)
|
79
79
|
end
|
80
|
-
else
|
81
|
-
warn "EM built without SSL support, skipping tests in #{__FILE__}"
|
82
80
|
end
|
@@ -15,6 +15,10 @@ class TestThreadedResource < Test::Unit::TestCase
|
|
15
15
|
|
16
16
|
def test_dispatch_completion
|
17
17
|
EM.run do
|
18
|
+
EM.add_timer(3) do
|
19
|
+
EM.stop
|
20
|
+
fail 'Resource dispatch timed out'
|
21
|
+
end
|
18
22
|
completion = resource.dispatch do |o|
|
19
23
|
o[:foo] = :bar
|
20
24
|
:foo
|
@@ -23,6 +27,10 @@ class TestThreadedResource < Test::Unit::TestCase
|
|
23
27
|
assert_equal :foo, result
|
24
28
|
EM.stop
|
25
29
|
end
|
30
|
+
completion.errback do |error|
|
31
|
+
EM.stop
|
32
|
+
fail "Unexpected error: #{error.message}"
|
33
|
+
end
|
26
34
|
end
|
27
35
|
assert_equal :bar, object[:foo]
|
28
36
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eventmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Francis Cianfrocca
|
@@ -9,8 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-02-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: test-unit
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
requirement: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ~>
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '2.0'
|
26
|
+
prerelease: false
|
27
|
+
type: :development
|
14
28
|
- !ruby/object:Gem::Dependency
|
15
29
|
name: rake-compiler
|
16
30
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -208,6 +222,7 @@ files:
|
|
208
222
|
- tests/test_line_protocol.rb
|
209
223
|
- tests/test_ltp.rb
|
210
224
|
- tests/test_ltp2.rb
|
225
|
+
- tests/test_many_fds.rb
|
211
226
|
- tests/test_next_tick.rb
|
212
227
|
- tests/test_object_protocol.rb
|
213
228
|
- tests/test_pause.rb
|