eventmachine-eventmachine 0.12.3 → 0.12.4

Sign up to get free protection for your applications and to get access to all the features.
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"