eventmachine-eventmachine 0.12.3 → 0.12.4

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/Rakefile CHANGED
@@ -46,11 +46,11 @@ end
46
46
 
47
47
  # If running under rubygems...
48
48
  __DIR__ ||= File.expand_path(File.dirname(__FILE__))
49
- if Gem.path.any? {|path| %r(^#{Regexp.escape path}) =~ __DIR__}
49
+ if Gem.path.map{|path| Dir.chdir(path){ Dir.pwd } }.any? {|path| %r(^#{Regexp.escape path}) =~ __DIR__}
50
50
  task :default => :gem_build
51
51
  else
52
52
  desc "Build gemspec, then build eventmachine, then run tests."
53
- task :default => [:gemspec, :build, :test]
53
+ task :default => [:build, :test]
54
54
  end
55
55
 
56
56
  desc ":default build when running under rubygems."
@@ -61,7 +61,7 @@ build_task = 'ext:build'
61
61
  build_task = 'java:build' if $eventmachine_library == :java
62
62
  build_task = :dummy_build if $eventmachine_library == :pure_ruby
63
63
  task :build => build_task do |t|
64
- Dir.glob('{ext,java/src}/*.{so,bundle,dll,jar}').each do |f|
64
+ Dir.glob('{ext,java/src,ext/fastfilereader}/*.{so,bundle,dll,jar}').each do |f|
65
65
  mv f, "lib"
66
66
  end
67
67
  end
@@ -73,8 +73,12 @@ task :clean do
73
73
  chdir 'ext' do
74
74
  sh "#{MAKE} clean" if test ?e, 'Makefile'
75
75
  end
76
+ chdir 'ext/fastfilereader' do
77
+ sh "#{MAKE} clean" if test ?e, 'Makefile'
78
+ end
76
79
  Dir.glob('**/Makefile').each { |file| rm file }
77
80
  Dir.glob('**/*.{o,so,bundle,class,jar,dll,log}').each { |file| rm file }
81
+ Dir.glob('ext/**/conftest.dSYM').each{ |file| rm_rf file }
78
82
  end
79
83
 
80
84
  Spec = Gem::Specification.new do |s|
@@ -121,22 +125,37 @@ using TCP/IP, especially if custom protocols are required.
121
125
  end
122
126
 
123
127
  namespace :ext do
128
+ ext_sources = FileList['ext/*.{h,cpp,rb,c}']
129
+ ffr_sources = FileList['ext/fastfilereader/*.{h,cpp,rb}']
130
+
124
131
  desc "Build C++ extension"
125
- task :build => [:clean, :make]
132
+ task :build => [:make]
126
133
 
127
- desc "make extension"
128
- task :make => [:makefile] do
134
+ desc "make extensions"
135
+ task :make => ext_sources + ['ext/Makefile'] do
129
136
  chdir 'ext' do
130
137
  sh MAKE
131
138
  end
132
139
  end
133
-
140
+ task :make => ffr_sources + ['ext/fastfilereader/Makefile'] do
141
+ chdir 'ext/fastfilereader' do
142
+ sh MAKE
143
+ end
144
+ end
145
+
134
146
  desc 'Compile the makefile'
135
- task :makefile do |t|
147
+ file 'ext/Makefile' => ext_sources do
136
148
  chdir 'ext' do
137
149
  ruby 'extconf.rb'
138
150
  end
139
151
  end
152
+
153
+ desc 'Compile fastfilereader makefile'
154
+ file 'ext/fastfilereader/Makefile' => ffr_sources do
155
+ chdir 'ext/fastfilereader' do
156
+ ruby 'extconf.rb'
157
+ end
158
+ end
140
159
  end
141
160
 
142
161
  namespace :java do
@@ -164,6 +183,9 @@ namespace :java do
164
183
  end
165
184
  end
166
185
 
167
- task :gemspec => :clean do
186
+ task :gemspec => :clobber do
168
187
  open("eventmachine.gemspec", 'w') { |f| f.write Spec.to_ruby }
169
188
  end
189
+
190
+ task :clobber => :clean
191
+ task :test => :build
data/ext/cmain.cpp CHANGED
@@ -30,7 +30,11 @@ extern "C" void ensure_eventmachine (const char *caller = "unknown caller")
30
30
  const int err_size = 128;
31
31
  char err_string[err_size];
32
32
  snprintf (err_string, err_size, "eventmachine not initialized: %s", caller);
33
- throw std::runtime_error (err_string);
33
+ #ifdef BUILD_FOR_RUBY
34
+ rb_raise(rb_eRuntimeError, err_string);
35
+ #else
36
+ throw std::runtime_error (err_string);
37
+ #endif
34
38
  }
35
39
  }
36
40
 
@@ -44,7 +48,11 @@ extern "C" void evma_initialize_library (void(*cb)(const char*, int, const char*
44
48
  // we're just being linked into.
45
49
  //InstallSignalHandlers();
46
50
  if (EventMachine)
47
- throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
51
+ #ifdef BUILD_FOR_RUBY
52
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_initialize_library");
53
+ #else
54
+ throw std::runtime_error ("eventmachine already initialized: evma_initialize_library");
55
+ #endif
48
56
  EventMachine = new EventMachine_t (cb);
49
57
  if (bUseEpoll)
50
58
  EventMachine->_UseEpoll();
@@ -113,8 +121,7 @@ evma_attach_fd
113
121
 
114
122
  extern "C" const char *evma_attach_fd (int file_descriptor, int notify_readable, int notify_writable)
115
123
  {
116
- if (!EventMachine)
117
- throw std::runtime_error ("not initialized");
124
+ ensure_eventmachine("evma_attach_fd");
118
125
  return EventMachine->AttachFD (file_descriptor, (notify_readable ? true : false), (notify_writable ? true : false));
119
126
  }
120
127
 
@@ -124,14 +131,16 @@ evma_detach_fd
124
131
 
125
132
  extern "C" int evma_detach_fd (const char *binding)
126
133
  {
127
- if (!EventMachine)
128
- throw std::runtime_error ("not initialized");
129
-
134
+ ensure_eventmachine("evma_dettach_fd");
130
135
  EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (binding));
131
136
  if (ed)
132
137
  return EventMachine->DetachFD (ed);
133
138
  else
134
- throw std::runtime_error ("invalid binding to detach");
139
+ #ifdef BUILD_FOR_RUBY
140
+ rb_raise(rb_eRuntimeError, "invalid binding to detach");
141
+ #else
142
+ throw std::runtime_error ("invalid binding to detach");
143
+ #endif
135
144
  }
136
145
 
137
146
  /**********************
@@ -396,8 +405,13 @@ evma_set_max_timer_count
396
405
  extern "C" void evma_set_max_timer_count (int ct)
397
406
  {
398
407
  // This may only be called if the reactor is not running.
408
+
399
409
  if (EventMachine)
400
- throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
410
+ #ifdef BUILD_FOR_RUBY
411
+ rb_raise(rb_eRuntimeError, "eventmachine already initialized: evma_set_max_timer_count");
412
+ #else
413
+ throw std::runtime_error ("eventmachine already initialized: evma_set_max_timer_count");
414
+ #endif
401
415
  EventMachine_t::SetMaxTimerCount (ct);
402
416
  }
403
417
 
data/ext/ed.cpp CHANGED
@@ -189,9 +189,7 @@ ConnectionDescriptor::ConnectionDescriptor (int sd, EventMachine_t *em):
189
189
  #ifdef HAVE_EPOLL
190
190
  EpollEvent.events = EPOLLOUT;
191
191
  #endif
192
- #ifdef HAVE_KQUEUE
193
- MyEventMachine->ArmKqueueWriter (this);
194
- #endif
192
+ // 22Jan09: Moved ArmKqueueWriter into SetConnectPending() to fix assertion failure in _WriteOutboundData()
195
193
  }
196
194
 
197
195
 
@@ -263,6 +261,17 @@ int ConnectionDescriptor::ReportErrorStatus (const char *binding)
263
261
  return -1;
264
262
  }
265
263
 
264
+ /***************************************
265
+ ConnectionDescriptor::SetConnectPending
266
+ ****************************************/
267
+
268
+ void ConnectionDescriptor::SetConnectPending(bool f)
269
+ {
270
+ bConnectPending = f;
271
+ #ifdef HAVE_KQUEUE
272
+ MyEventMachine->ArmKqueueWriter (this);
273
+ #endif
274
+ }
266
275
 
267
276
 
268
277
  /**************************************
@@ -624,29 +633,36 @@ void ConnectionDescriptor::_WriteOutboundData()
624
633
  assert (GetSocket() != INVALID_SOCKET);
625
634
  int bytes_written = send (GetSocket(), output_buffer, nbytes, 0);
626
635
 
627
- if (bytes_written > 0) {
628
- OutboundDataSize -= bytes_written;
629
- if ((size_t)bytes_written < nbytes) {
630
- int len = nbytes - bytes_written;
631
- char *buffer = (char*) malloc (len + 1);
632
- if (!buffer)
633
- throw std::runtime_error ("bad alloc throwing back data");
634
- memcpy (buffer, output_buffer + bytes_written, len);
635
- buffer [len] = 0;
636
- OutboundPages.push_front (OutboundPage (buffer, len));
637
- }
636
+ bool err = false;
637
+ if (bytes_written < 0) {
638
+ err = true;
639
+ bytes_written = 0;
640
+ }
638
641
 
639
- #ifdef HAVE_EPOLL
640
- EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0));
641
- assert (MyEventMachine);
642
- MyEventMachine->Modify (this);
643
- #endif
644
- #ifdef HAVE_KQUEUE
645
- if (SelectForWrite())
646
- MyEventMachine->ArmKqueueWriter (this);
647
- #endif
642
+ assert (bytes_written >= 0);
643
+ OutboundDataSize -= bytes_written;
644
+ if ((size_t)bytes_written < nbytes) {
645
+ int len = nbytes - bytes_written;
646
+ char *buffer = (char*) malloc (len + 1);
647
+ if (!buffer)
648
+ throw std::runtime_error ("bad alloc throwing back data");
649
+ memcpy (buffer, output_buffer + bytes_written, len);
650
+ buffer [len] = 0;
651
+ OutboundPages.push_front (OutboundPage (buffer, len));
648
652
  }
649
- else {
653
+
654
+ #ifdef HAVE_EPOLL
655
+ EpollEvent.events = (EPOLLIN | (SelectForWrite() ? EPOLLOUT : 0));
656
+ assert (MyEventMachine);
657
+ MyEventMachine->Modify (this);
658
+ #endif
659
+ #ifdef HAVE_KQUEUE
660
+ if (SelectForWrite())
661
+ MyEventMachine->ArmKqueueWriter (this);
662
+ #endif
663
+
664
+
665
+ if (err) {
650
666
  #ifdef OS_UNIX
651
667
  if ((errno != EINPROGRESS) && (errno != EWOULDBLOCK) && (errno != EINTR))
652
668
  #endif
data/ext/ed.h CHANGED
@@ -85,7 +85,14 @@ class EventableDescriptor: public Bindable_t
85
85
 
86
86
  protected:
87
87
  enum {
88
- PendingConnectTimeout = 4 // can easily be made an instance variable
88
+ // 4 seconds is too short, most other libraries default to OS settings
89
+ // which in 2.6 kernel defaults to a 60 second connect timeout.
90
+ //
91
+ // Curl-Multi: http://curl.haxx.se/mail/lib-2001-01/0019.html
92
+ //
93
+ // updating to 50 seconds, so we catch it before the OS does
94
+
95
+ PendingConnectTimeout = 50 // can easily be made an instance variable
89
96
  };
90
97
 
91
98
  void (*EventCallback)(const char*, int, const char*, int);
@@ -139,7 +146,7 @@ class ConnectionDescriptor: public EventableDescriptor
139
146
 
140
147
  int SendOutboundData (const char*, int);
141
148
 
142
- void SetConnectPending (bool f) { bConnectPending = f; }
149
+ void SetConnectPending (bool f);
143
150
 
144
151
  void SetNotifyReadable (bool readable) { bNotifyReadable = readable; }
145
152
  void SetNotifyWritable (bool writable) { bNotifyWritable = writable; }
data/ext/em.cpp CHANGED
@@ -426,7 +426,16 @@ bool EventMachine_t::_RunEpollOnce()
426
426
  #ifdef HAVE_EPOLL
427
427
  assert (epfd != -1);
428
428
  struct epoll_event ev [MaxEpollDescriptors];
429
- int s = epoll_wait (epfd, ev, MaxEpollDescriptors, 50);
429
+ int s;
430
+
431
+ #ifdef BUILD_FOR_RUBY
432
+ TRAP_BEG;
433
+ #endif
434
+ s = epoll_wait (epfd, ev, MaxEpollDescriptors, 50);
435
+ #ifdef BUILD_FOR_RUBY
436
+ TRAP_END;
437
+ #endif
438
+
430
439
  if (s > 0) {
431
440
  for (int i=0; i < s; i++) {
432
441
  EventableDescriptor *ed = (EventableDescriptor*) ev[i].data.ptr;
@@ -511,8 +520,11 @@ bool EventMachine_t::_RunEpollOnce()
511
520
  }
512
521
  }
513
522
 
514
- timeval tv = {0,0};
515
- EmSelect (0, NULL, NULL, NULL, &tv);
523
+ #ifdef BUILD_FOR_RUBY
524
+ if (!rb_thread_alone()) {
525
+ rb_thread_schedule();
526
+ }
527
+ #endif
516
528
 
517
529
  return true;
518
530
  #else
@@ -533,7 +545,14 @@ bool EventMachine_t::_RunKqueueOnce()
533
545
  struct kevent Karray [maxKevents];
534
546
  struct timespec ts = {0, 10000000}; // Too frequent. Use blocking_region
535
547
 
536
- int k = kevent (kqfd, NULL, 0, Karray, maxKevents, &ts);
548
+ int k;
549
+ #ifdef BUILD_FOR_RUBY
550
+ TRAP_BEG;
551
+ #endif
552
+ k = kevent (kqfd, NULL, 0, Karray, maxKevents, &ts);
553
+ #ifdef BUILD_FOR_RUBY
554
+ TRAP_END;
555
+ #endif
537
556
  struct kevent *ke = Karray;
538
557
  while (k > 0) {
539
558
  EventableDescriptor *ed = (EventableDescriptor*) (ke->udata);
@@ -587,8 +606,11 @@ bool EventMachine_t::_RunKqueueOnce()
587
606
 
588
607
 
589
608
  // TODO, replace this with rb_thread_blocking_region for 1.9 builds.
590
- timeval tv = {0,0};
591
- EmSelect (0, NULL, NULL, NULL, &tv);
609
+ #ifdef BUILD_FOR_RUBY
610
+ if (!rb_thread_alone()) {
611
+ rb_thread_schedule();
612
+ }
613
+ #endif
592
614
 
593
615
  return true;
594
616
  #else
data/ext/em.h CHANGED
@@ -33,6 +33,13 @@ See the file COPYING for complete licensing information.
33
33
  #ifdef BUILD_FOR_RUBY
34
34
  #include <ruby.h>
35
35
  #define EmSelect rb_thread_select
36
+
37
+ #ifdef HAVE_RBTRAP
38
+ #include <rubysig.h>
39
+ #else
40
+ #define TRAP_BEG
41
+ #define TRAP_END
42
+ #endif
36
43
  #else
37
44
  #define EmSelect select
38
45
  #endif
data/ext/extconf.rb CHANGED
@@ -33,7 +33,7 @@ end
33
33
  require 'mkmf'
34
34
 
35
35
  add_define 'BUILD_FOR_RUBY'
36
-
36
+ add_define 'HAVE_RBTRAP' if have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
37
37
  add_define "HAVE_TBR" if have_func('rb_thread_blocking_region') and have_macro('RB_UBF_DFL', 'ruby.h')
38
38
 
39
39
  # Minor platform details between *nix and Windows:
@@ -0,0 +1,161 @@
1
+ # $Id: extconf.rb 4526 2007-07-03 18:04:34Z francis $
2
+ #
3
+ #----------------------------------------------------------------------------
4
+ #
5
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
6
+ # Gmail: garbagecat10
7
+ #
8
+ # This program is free software; you can redistribute it and/or modify
9
+ # it under the terms of either: 1) the GNU General Public License
10
+ # as published by the Free Software Foundation; either version 2 of the
11
+ # License, or (at your option) any later version; or 2) Ruby's License.
12
+ #
13
+ # See the file COPYING for complete licensing information.
14
+ #
15
+ #---------------------------------------------------------------------------
16
+ #
17
+ # extconf.rb for Fast File Reader
18
+ # We have to munge LDSHARED because this code needs a C++ link.
19
+ #
20
+
21
+ require 'mkmf'
22
+
23
+ flags = []
24
+
25
+ case RUBY_PLATFORM.split('-',2)[1]
26
+ when 'mswin32', 'mingw32', 'bccwin32'
27
+ unless have_header('windows.h') and
28
+ have_header('winsock.h') and
29
+ have_library('kernel32') and
30
+ have_library('rpcrt4') and
31
+ have_library('gdi32')
32
+ exit
33
+ end
34
+
35
+ flags << "-D OS_WIN32"
36
+ flags << '-D BUILD_FOR_RUBY'
37
+ flags << "-EHs"
38
+ flags << "-GR"
39
+
40
+ dir_config('ssl')
41
+ if have_library('ssleay32') and
42
+ have_library('libeay32') and
43
+ have_header('openssl/ssl.h') and
44
+ have_header('openssl/err.h')
45
+ flags << '-D WITH_SSL'
46
+ else
47
+ flags << '-D WITHOUT_SSL'
48
+ end
49
+
50
+ when /solaris/
51
+ unless have_library('pthread') and
52
+ have_library('nsl') and
53
+ have_library('socket')
54
+ exit
55
+ end
56
+
57
+ flags << '-D OS_UNIX'
58
+ flags << '-D OS_SOLARIS8'
59
+ flags << '-D BUILD_FOR_RUBY'
60
+
61
+ dir_config('ssl')
62
+ if have_library('ssl') and
63
+ have_library('crypto') and
64
+ have_header('openssl/ssl.h') and
65
+ have_header('openssl/err.h')
66
+ flags << '-D WITH_SSL'
67
+ else
68
+ flags << '-D WITHOUT_SSL'
69
+ end
70
+
71
+ # on Unix we need a g++ link, not gcc.
72
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
73
+
74
+ when /darwin/
75
+ flags << '-DOS_UNIX'
76
+ flags << '-DBUILD_FOR_RUBY'
77
+
78
+ dir_config('ssl')
79
+ if have_library('ssl') and
80
+ have_library('crypto') and
81
+ have_library('C') and
82
+ have_header('openssl/ssl.h') and
83
+ have_header('openssl/err.h')
84
+ flags << '-DWITH_SSL'
85
+ else
86
+ flags << '-DWITHOUT_SSL'
87
+ end
88
+ # on Unix we need a g++ link, not gcc.
89
+ # Ff line contributed by Daniel Harple.
90
+ CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
91
+
92
+ when /linux/
93
+ unless have_library('pthread')
94
+ exit
95
+ end
96
+
97
+ flags << '-DOS_UNIX'
98
+ flags << '-DBUILD_FOR_RUBY'
99
+
100
+ # Original epoll test is inadequate because 2.4 kernels have the header
101
+ # but not the code.
102
+ #flags << '-DHAVE_EPOLL' if have_header('sys/epoll.h')
103
+ if have_header('sys/epoll.h')
104
+ File.open("hasEpollTest.c", "w") {|f|
105
+ f.puts "#include <sys/epoll.h>"
106
+ f.puts "int main() { epoll_create(1024); return 0;}"
107
+ }
108
+ (e = system( "gcc hasEpollTest.c -o hasEpollTest " )) and (e = $?.to_i)
109
+ `rm -f hasEpollTest.c hasEpollTest`
110
+ flags << '-DHAVE_EPOLL' if e == 0
111
+ end
112
+
113
+ dir_config('ssl')
114
+ if have_library('ssl') and
115
+ have_library('crypto') and
116
+ have_header('openssl/ssl.h') and
117
+ have_header('openssl/err.h')
118
+ flags << '-DWITH_SSL'
119
+ else
120
+ flags << '-DWITHOUT_SSL'
121
+ end
122
+ # on Unix we need a g++ link, not gcc.
123
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
124
+
125
+ # Modify the mkmf constant LINK_SO so the generated shared object is stripped.
126
+ # You might think modifying CONFIG['LINK_SO'] would be a better way to do this,
127
+ # but it doesn't work because mkmf doesn't look at CONFIG['LINK_SO'] again after
128
+ # it initializes.
129
+ linkso = Object.send :remove_const, "LINK_SO"
130
+ LINK_SO = linkso + "; strip $@"
131
+
132
+ else
133
+ unless have_library('pthread')
134
+ exit
135
+ end
136
+
137
+ flags << '-DOS_UNIX'
138
+ flags << '-DBUILD_FOR_RUBY'
139
+
140
+ dir_config('ssl')
141
+ if have_library('ssl') and
142
+ have_library('crypto') and
143
+ have_header('openssl/ssl.h') and
144
+ have_header('openssl/err.h')
145
+ flags << '-DWITH_SSL'
146
+ else
147
+ flags << '-DWITHOUT_SSL'
148
+ end
149
+ # on Unix we need a g++ link, not gcc.
150
+ CONFIG['LDSHARED'] = "$(CXX) -shared"
151
+
152
+ end
153
+
154
+ if $CPPFLAGS
155
+ $CPPFLAGS += ' ' + flags.join(' ')
156
+ else
157
+ $CFLAGS += ' ' + flags.join(' ')
158
+ end
159
+
160
+
161
+ create_makefile "fastfilereaderext"