eventmachine 0.8.0 → 0.8.1

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.
@@ -1,4 +1,4 @@
1
- # $Id: extconf.rb 385 2007-06-16 11:38:59Z blackhedd $
1
+ # $Id: extconf.rb 404 2007-07-13 01:07:28Z blackhedd $
2
2
  #
3
3
  #----------------------------------------------------------------------------
4
4
  #
@@ -71,6 +71,12 @@ when /solaris/
71
71
  # on Unix we need a g++ link, not gcc.
72
72
  CONFIG['LDSHARED'] = "$(CXX) -shared"
73
73
 
74
+ # Patch by Tim Pease, fixes SUNWspro compile problems.
75
+ if CONFIG['CC'] == 'cc'
76
+ $CFLAGS = CONFIG['CFLAGS'] = "-g -O2 -fPIC"
77
+ CONFIG['CCDLFLAGS'] = "-fPIC"
78
+ end
79
+
74
80
  when /darwin/
75
81
  flags << '-DOS_UNIX'
76
82
  flags << '-DBUILD_FOR_RUBY'
@@ -1,6 +1,6 @@
1
1
  /*****************************************************************************
2
2
 
3
- $Id: project.h 401 2007-07-11 12:54:06Z blackhedd $
3
+ $Id: project.h 490 2007-07-30 12:51:33Z blackhedd $
4
4
 
5
5
  File: project.h
6
6
  Date: 06Apr06
@@ -39,7 +39,10 @@ See the file COPYING for complete licensing information.
39
39
  #ifdef OS_UNIX
40
40
  #include <signal.h>
41
41
  #include <netdb.h>
42
+ #include <time.h>
43
+ #include <sys/time.h>
42
44
  #include <sys/types.h>
45
+ #include <sys/stat.h>
43
46
  #include <sys/socket.h>
44
47
  #include <sys/un.h>
45
48
  #include <sys/resource.h>
@@ -62,8 +65,10 @@ typedef int SOCKET;
62
65
  #ifndef AF_LOCAL
63
66
  #define AF_LOCAL AF_UNIX
64
67
  #endif
65
- // The ff is superfluous on Solaris > 7. Thanks to Brett Eisenberg.
66
- //#define INADDR_NONE ((unsigned long)-1)
68
+ // INADDR_NONE is undefined on Solaris < 8. Thanks to Brett Eisenberg and Tim Pease.
69
+ #ifndef INADDR_NONE
70
+ #define INADDR_NONE ((unsigned long)-1)
71
+ #endif
67
72
  #endif
68
73
  #endif
69
74
 
@@ -100,6 +105,7 @@ using namespace std;
100
105
  #include "page.h"
101
106
  #include "ssl.h"
102
107
  #include "eventmachine.h"
108
+ #include "eventmachine_cpp.h"
103
109
 
104
110
 
105
111
 
@@ -1,6 +1,6 @@
1
1
  /*****************************************************************************
2
2
 
3
- $Id: rubymain.cpp 377 2007-06-13 01:05:56Z blackhedd $
3
+ $Id: rubymain.cpp 476 2007-07-27 03:32:51Z blackhedd $
4
4
 
5
5
  File: rubymain.cpp
6
6
  Date: 06Apr06
@@ -92,6 +92,16 @@ static VALUE t_start_server (VALUE self, VALUE server, VALUE port)
92
92
  return rb_str_new2 (f);
93
93
  }
94
94
 
95
+ /*************
96
+ t_stop_server
97
+ *************/
98
+
99
+ static VALUE t_stop_server (VALUE self, VALUE signature)
100
+ {
101
+ evma_stop_tcp_server (StringValuePtr (signature));
102
+ return Qnil;
103
+ }
104
+
95
105
 
96
106
  /*******************
97
107
  t_start_unix_server
@@ -363,6 +373,37 @@ static VALUE t__epoll (VALUE self)
363
373
  }
364
374
 
365
375
 
376
+ /****************
377
+ t_send_file_data
378
+ ****************/
379
+
380
+ static VALUE t_send_file_data (VALUE self, VALUE signature, VALUE filename)
381
+ {
382
+
383
+ /* The current implementation of evma_send_file_data_to_connection enforces a strict
384
+ * upper limit on the file size it will transmit (currently 32K). The function returns
385
+ * zero on success, -1 if the requested file exceeds its size limit, and a positive
386
+ * number for other errors.
387
+ * TODO: Positive return values are actually errno's, which is probably the wrong way to
388
+ * do this. For one thing it's ugly. For another, we can't be sure zero is never a real errno.
389
+ */
390
+
391
+ int b = evma_send_file_data_to_connection (StringValuePtr(signature), StringValuePtr(filename));
392
+ if (b == -1)
393
+ rb_raise(rb_eRuntimeError, "File too large. send_file_data() supports files under 32k.");
394
+ if (b > 0) {
395
+ char *err = strerror (b);
396
+ char buf[1024];
397
+ memset (buf, 0, sizeof(buf));
398
+ snprintf (buf, sizeof(buf)-1, ": %s %s", StringValuePtr(filename),(err?err:"???"));
399
+
400
+ rb_raise (rb_eIOError, buf);
401
+ }
402
+
403
+ return INT2NUM (0);
404
+ }
405
+
406
+
366
407
  /*******************
367
408
  t_set_rlimit_nofile
368
409
  *******************/
@@ -409,6 +450,7 @@ extern "C" void Init_rubyeventmachine()
409
450
  rb_define_module_function (EmModule, "run_machine_without_threads", (VALUE(*)(...))t_run_machine_without_threads, 0);
410
451
  rb_define_module_function (EmModule, "add_oneshot_timer", (VALUE(*)(...))t_add_oneshot_timer, 1);
411
452
  rb_define_module_function (EmModule, "start_tcp_server", (VALUE(*)(...))t_start_server, 2);
453
+ rb_define_module_function (EmModule, "stop_tcp_server", (VALUE(*)(...))t_stop_server, 1);
412
454
  rb_define_module_function (EmModule, "start_unix_server", (VALUE(*)(...))t_start_unix_server, 1);
413
455
  rb_define_module_function (EmModule, "start_tls", (VALUE(*)(...))t_start_tls, 1);
414
456
  rb_define_module_function (EmModule, "send_data", (VALUE(*)(...))t_send_data, 3);
@@ -424,6 +466,7 @@ extern "C" void Init_rubyeventmachine()
424
466
  rb_define_module_function (EmModule, "set_timer_quantum", (VALUE(*)(...))t_set_timer_quantum, 1);
425
467
  rb_define_module_function (EmModule, "setuid_string", (VALUE(*)(...))t_setuid_string, 1);
426
468
  rb_define_module_function (EmModule, "invoke_popen", (VALUE(*)(...))t_invoke_popen, 1);
469
+ rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
427
470
 
428
471
  // Provisional:
429
472
  rb_define_module_function (EmModule, "_write_file", (VALUE(*)(...))t__write_file, 1);
@@ -1,4 +1,4 @@
1
- # $Id: deferrable.rb 320 2007-05-22 22:12:59Z blackhedd $
1
+ # $Id: deferrable.rb 464 2007-07-22 12:56:27Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -34,7 +34,7 @@ module Deferrable
34
34
  block.call(*@deferred_args)
35
35
  else
36
36
  @callbacks ||= []
37
- @callbacks << block
37
+ @callbacks.unshift block # << block
38
38
  end
39
39
  end
40
40
 
@@ -44,7 +44,7 @@ module Deferrable
44
44
  block.call(*@deferred_args)
45
45
  else
46
46
  @errbacks ||= []
47
- @errbacks << block
47
+ @errbacks.unshift block # << block
48
48
  end
49
49
  end
50
50
 
@@ -66,19 +66,23 @@ module Deferrable
66
66
  # means that a callback can call #set_deferred_status and change the parameters
67
67
  # that will be sent to subsequent callbacks down the chain.
68
68
  #
69
+ # Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion
70
+ # by Kirk Haines, to work around the memory leak bug that still exists in many Ruby
71
+ # versions.
72
+ #
69
73
  def set_deferred_status arg, *args
70
74
  @deferred_status = arg
71
75
  @deferred_args = args
72
76
  case @deferred_status
73
77
  when :succeeded
74
78
  if @callbacks
75
- while cb = @callbacks.shift
79
+ while cb = @callbacks.pop #shift
76
80
  cb.call(*@deferred_args)
77
81
  end
78
82
  end
79
83
  when :failed
80
84
  if @errbacks
81
- while eb = @errbacks.shift
85
+ while eb = @errbacks.pop #shift
82
86
  eb.call(*@deferred_args)
83
87
  end
84
88
  end
@@ -97,6 +101,27 @@ module Deferrable
97
101
  set_deferred_status :failed, *args
98
102
  end
99
103
 
104
+ # And still more sugar
105
+ #
106
+ def succeed *args
107
+ set_deferred_success *args
108
+ end
109
+
110
+ # Can't get enough sugar
111
+ #
112
+ def fail *args
113
+ set_deferred_failure *args
114
+ end
100
115
  end
116
+
117
+
118
+ # DefaultDeferrable is an otherwise empty class that includes Deferrable.
119
+ # This is very useful when you just need to return a Deferrable object
120
+ # as a way of communicating deferred status to some other part of a program.
121
+ #
122
+ class DefaultDeferrable
123
+ include Deferrable
124
+ end
125
+
101
126
  end
102
127
 
@@ -0,0 +1,114 @@
1
+ # $Id: streamer.rb 476 2007-07-27 03:32:51Z blackhedd $
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 Jul 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ module EventMachine
28
+ class FileStreamer
29
+ MappingThreshold = 16384
30
+ BackpressureLevel = 50000
31
+ ChunkSize = 16384
32
+
33
+ include Deferrable
34
+ def initialize connection, filename, args
35
+ @connection = connection
36
+ @http_chunks = args[:http_chunks]
37
+
38
+ if File.exist?(filename)
39
+ @size = File.size?(filename)
40
+ if @size <= MappingThreshold
41
+ stream_without_mapping filename
42
+ else
43
+ stream_with_mapping filename
44
+ end
45
+ else
46
+ fail "file not found"
47
+ end
48
+ end
49
+
50
+ def stream_without_mapping filename
51
+ if @http_chunks
52
+ #@connection.send_data "#{format("%x",@size)}\r\n"
53
+ @connection.send_data "#{@size.to_s(16)}\r\n"
54
+ @connection.send_file_data filename
55
+ @connection.send_data "\r\n0\r\n\r\n"
56
+ else
57
+ @connection.send_file_data filename
58
+ end
59
+ succeed
60
+ end
61
+ private :stream_without_mapping
62
+
63
+ def stream_with_mapping filename
64
+ ensure_mapping_extension_is_present
65
+
66
+ @position = 0
67
+ @mapping = EventMachine::FastFileReader::Mapper.new filename
68
+ stream_one_chunk
69
+ end
70
+ private :stream_with_mapping
71
+
72
+ def stream_one_chunk
73
+ loop {
74
+ if @position < @size
75
+ if @connection.get_outbound_data_size > BackpressureLevel
76
+ EventMachine::next_tick {stream_one_chunk}
77
+ break
78
+ else
79
+ len = @size - @position
80
+ len = ChunkSize if (len > ChunkSize)
81
+
82
+ #@connection.send_data( "#{format("%x",len)}\r\n" ) if @http_chunks
83
+ @connection.send_data( "#{len.to_s(16)}\r\n" ) if @http_chunks
84
+ @connection.send_data( @mapping.get_chunk( @position, len ))
85
+ @connection.send_data("\r\n") if @http_chunks
86
+
87
+ @position += len
88
+ end
89
+ else
90
+ @connection.send_data "0\r\n\r\n" if @http_chunks
91
+ @mapping.close
92
+ succeed
93
+ break
94
+ end
95
+ }
96
+ end
97
+
98
+ #--
99
+ # We use an outboard extension class to get memory-mapped files.
100
+ # It's outboard to avoid polluting the core distro, but that means
101
+ # there's a "hidden" dependency on it. The first time we get here in
102
+ # any run, try to load up the dependency extension. User code will see
103
+ # a LoadError if it's not available, but code that doesn't require
104
+ # mapped files will work fine without it. This is a somewhat difficult
105
+ # compromise between usability and proper modularization.
106
+ #
107
+ def ensure_mapping_extension_is_present
108
+ @@fastfilereader ||= (require 'fastfilereaderext')
109
+ end
110
+ private :ensure_mapping_extension_is_present
111
+
112
+ end
113
+ end
114
+
@@ -1,4 +1,4 @@
1
- # $Id: eventmachine.rb 393 2007-07-06 06:51:47Z blackhedd $
1
+ # $Id: eventmachine.rb 489 2007-07-30 05:10:15Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -50,7 +50,14 @@ else
50
50
  end
51
51
  end
52
52
  =end
53
- require 'rubyeventmachine'
53
+
54
+
55
+ if RUBY_PLATFORM =~ /java/
56
+ require 'java'
57
+ require 'jeventmachine'
58
+ else
59
+ require 'rubyeventmachine'
60
+ end
54
61
 
55
62
 
56
63
  require "eventmachine_version"
@@ -58,6 +65,7 @@ require 'em/deferrable'
58
65
  require 'em/future'
59
66
  require 'em/eventable'
60
67
  require 'em/messages'
68
+ require 'em/streamer'
61
69
 
62
70
  require 'shellwords'
63
71
 
@@ -467,9 +475,19 @@ module EventMachine
467
475
 
468
476
  s = start_tcp_server server, port
469
477
  @acceptors[s] = [klass,block]
478
+ s
470
479
  end
471
480
 
472
481
 
482
+ # Stop a TCP server socket that was started with EventMachine#start_server.
483
+ #--
484
+ # Requested by Kirk Haines. TODO, this isn't OOP enough. We ought somehow
485
+ # to have #start_server return an object that has a close or a stop method on it.
486
+ #
487
+ def EventMachine::stop_server signature
488
+ EventMachine::stop_tcp_server signature
489
+ end
490
+
473
491
  def EventMachine::start_unix_domain_server filename, handler=nil, &block
474
492
  klass = if (handler and handler.is_a?(Class))
475
493
  handler
@@ -1226,6 +1244,34 @@ class Connection
1226
1244
  end
1227
1245
 
1228
1246
 
1247
+ # Like EventMachine::Connection#send_data, this sends data to the remote end of
1248
+ # the network connection. EventMachine::Connection@send_file_data takes a
1249
+ # filename as an argument, though, and sends the contents of the file, in one
1250
+ # chunk. Contributed by Kirk Haines.
1251
+ #
1252
+ def send_file_data filename
1253
+ EventMachine::send_file_data @signature, filename
1254
+ end
1255
+
1256
+ # Open a file on the filesystem and send it to the remote peer. This returns an
1257
+ # object of type EventMachine::Deferrable. The object's callbacks will be executed
1258
+ # on the reactor main thread when the file has been completely scheduled for
1259
+ # transmission to the remote peer. Its errbacks will be called in case of an error
1260
+ # (such as file-not-found). #stream_file_data employs various strategems to achieve
1261
+ # the fastest possible performance, balanced against minimum consumption of memory.
1262
+ #
1263
+ # You can control the behavior of #stream_file_data with the optional arguments parameter.
1264
+ # Currently-supported arguments are:
1265
+ # :http_chunks, a boolean flag which defaults false. If true, this flag streams the
1266
+ # file data in a format compatible with the HTTP chunked-transfer encoding.
1267
+ #
1268
+ # Warning: this feature has an implicit dependency on an outboard extension,
1269
+ # evma_fastfilereader. You must install this extension in order to use #stream_file_data
1270
+ # with files larger than a certain size (currently 8192 bytes).
1271
+ #
1272
+ def stream_file_data filename, args={}
1273
+ EventMachine::FileStreamer.new( self, filename, args )
1274
+ end
1229
1275
 
1230
1276
 
1231
1277
  # TODO, document this
@@ -1284,4 +1330,6 @@ require 'protocols/tcptest'
1284
1330
  require 'protocols/httpclient'
1285
1331
  require 'protocols/line_and_text'
1286
1332
  require 'protocols/header_and_content'
1333
+ require 'protocols/linetext2'
1334
+ require 'protocols/stomp'
1287
1335
 
@@ -1,4 +1,4 @@
1
- # $Id: eventmachine_version.rb 389 2007-06-25 02:07:04Z blackhedd $
1
+ # $Id: eventmachine_version.rb 482 2007-07-28 19:11:03Z blackhedd $
2
2
  #
3
3
  # Author:: Francis Cianfrocca (gmail: blackhedd)
4
4
  # Homepage:: http://rubyeventmachine.com
@@ -25,7 +25,7 @@
25
25
 
26
26
  module EventMachine
27
27
 
28
- VERSION = "0.8.0"
28
+ VERSION = "0.8.1"
29
29
 
30
30
  end
31
31
 
@@ -0,0 +1,106 @@
1
+ # $Id: jeventmachine.rb 451 2007-07-21 13:34:28Z blackhedd $
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 8 Apr 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+
27
+ # This module provides "glue" for the Java version of the EventMachine reactor core.
28
+ # For C++ EventMachines, the analogous functionality is found in ext/rubymain.cpp,
29
+ # which is a garden-variety Ruby-extension glue module.
30
+
31
+
32
+ require 'em_reactor'
33
+
34
+ module EventMachine
35
+ # TODO: These event numbers are defined in way too many places.
36
+ # DRY them up.
37
+ TimerFired = 100
38
+ ConnectionData = 101
39
+ ConnectionUnbound = 102
40
+ ConnectionAccepted = 103
41
+ ConnectionCompleted = 104
42
+ LoopbreakSignalled = 105
43
+
44
+ class EM < com.rubyeventmachine.EmReactor
45
+ def eventCallback a1, a2, a3
46
+ s = String.from_java_bytes(a3.array[a3.position...a3.limit])
47
+ EventMachine::event_callback a1, a2, s
48
+ end
49
+ end
50
+ def self.initialize_event_machine
51
+ @em = EM.new
52
+ end
53
+ def self.release_machine
54
+ @em = nil
55
+ end
56
+ def self.add_oneshot_timer interval
57
+ @em.installOneshotTimer interval
58
+ end
59
+ def self.run_machine
60
+ @em.run
61
+ end
62
+ def self.stop
63
+ @em.stop
64
+ end
65
+ def self.start_tcp_server server, port
66
+ @em.startTcpServer server, port
67
+ end
68
+ def self.stop_tcp_server sig
69
+ @em.stopTcpServer sig
70
+ end
71
+ def self.send_data sig, data, length
72
+ @em.sendData sig, data, length
73
+ end
74
+ def self.send_datagram sig, data, length, address, port
75
+ @em.sendDatagram sig, data, length, address, port
76
+ end
77
+ def self.connect_server server, port
78
+ @em.connectTcpServer server, port
79
+ end
80
+ def self.close_connection sig, after_writing
81
+ @em.closeConnection sig, after_writing
82
+ end
83
+ def self.start_tls sig
84
+ @em.startTls sig
85
+ end
86
+ def self.signal_loopbreak
87
+ @em.signalLoopbreak
88
+ end
89
+ def self.set_timer_quantum q
90
+ @em.setTimerQuantum q
91
+ end
92
+ def self.epoll
93
+ # Epoll is a no-op for Java.
94
+ # The latest Java versions run epoll when possible in NIO.
95
+ end
96
+ def self.set_rlimit_nofile n_descriptors
97
+ # Currently a no-op for Java.
98
+ end
99
+ def self.open_udp_socket server, port
100
+ @em.openUdpSocket server, port
101
+ end
102
+ def self.library_type
103
+ :java
104
+ end
105
+ end
106
+