eventmachine 0.8.0 → 0.8.1

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