eventmachine 1.0.4 → 1.0.5
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/.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 +19 -3
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
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,8 +10,24 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2015-02-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: test-unit
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2.0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '2.0'
|
15
31
|
- !ruby/object:Gem::Dependency
|
16
32
|
name: rake-compiler
|
17
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -240,6 +256,7 @@ files:
|
|
240
256
|
- tests/test_line_protocol.rb
|
241
257
|
- tests/test_ltp.rb
|
242
258
|
- tests/test_ltp2.rb
|
259
|
+
- tests/test_many_fds.rb
|
243
260
|
- tests/test_next_tick.rb
|
244
261
|
- tests/test_object_protocol.rb
|
245
262
|
- tests/test_pause.rb
|
@@ -305,4 +322,3 @@ signing_key:
|
|
305
322
|
specification_version: 3
|
306
323
|
summary: Ruby/EventMachine library
|
307
324
|
test_files: []
|
308
|
-
has_rdoc:
|