eventmachine-win32 0.5.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/RELEASE_NOTES CHANGED
@@ -1,7 +1,20 @@
1
- $Id: RELEASE_NOTES 64 2006-05-17 07:00:16Z blackhedd $
1
+ $Id: RELEASE_NOTES 223 2006-08-08 20:30:41Z blackhedd $
2
2
 
3
3
  RUBY/EventMachine RELEASE NOTES
4
4
 
5
+ --------------------------------------------------
6
+ Version: 0.7.0, released xxAug06
7
+ Added a fix in em.cpp/ConnectToServer to fix a fatal exception that
8
+ occurred in FreeBSD when connecting successfully to a remote server.
9
+
10
+ --------------------------------------------------
11
+ Version: 0.6.0, released xxJul06
12
+ Added deferred operations, suggested by Don Stocks, amillionhitpoints@yahoo.com.
13
+
14
+ --------------------------------------------------
15
+ Version: 0.5.4, released xxJun06
16
+ Added get_peername support for streams and datagrams.
17
+
5
18
  --------------------------------------------------
6
19
  Version: 0.5.3, released 17May06
7
20
  Fixed bugs in extconf.rb, thanks to Daniel Harple, dharple@generalconsumption.org.
data/TODO ADDED
@@ -0,0 +1,10 @@
1
+ $Id: TODO 231 2006-08-13 17:15:53Z blackhedd $
2
+
3
+ TODO List:
4
+
5
+ 12Aug06: Noticed by Don Stocks. A TCP connect-request that results
6
+ in a failed DNS resolution fires a fatal error back to user code.
7
+ Uuuuuugly. We should probably cause an unbind event to get fired
8
+ instead, and add some parameterization so the caller can detect
9
+ the nature of the failure.
10
+
@@ -0,0 +1,89 @@
1
+ # $Id: deferrable.rb 216 2006-07-17 10:20:42Z blackhedd $
2
+ #
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
+ # Date:: 16 July 2006
5
+ #
6
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
+ #
8
+ # This program is made available under the terms of the GPL version 2.
9
+ #
10
+ # See EventMachine and EventMachine::Connection for documentation and
11
+ # usage examples.
12
+ #
13
+ #----------------------------------------------------------------------------
14
+ #
15
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
16
+ #
17
+ # Gmail: garbagecat10
18
+ #
19
+ # This program is free software; you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation; either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program; if not, write to the Free Software
31
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+ require 'forwardable'
38
+
39
+ module EventMachine
40
+
41
+ module Deferrable
42
+ def callback &block
43
+ return unless block
44
+ if @deferred_status == :succeeded
45
+ block.call
46
+ else
47
+ @callbacks ||= []
48
+ @callbacks << block
49
+ end
50
+ end
51
+
52
+ def errback &block
53
+ return unless block
54
+ if @deferred_status == :failed
55
+ block.call
56
+ else
57
+ @errbacks ||= []
58
+ @errbacks << block
59
+ end
60
+ end
61
+
62
+ # Note that if you call this method without arguments,
63
+ # no arguments will be passed to the callback/errback.
64
+ # If the user has coded these with arguments, then the
65
+ # user code will throw an argument exception.
66
+ # Implementors of deferrable classes <b>must</b>
67
+ # document the arguments they will supply to user callbacks.
68
+ def set_deferred_status arg, *args
69
+ @deferred_status = arg
70
+ @deferred_args = args
71
+ case @deferred_status
72
+ when :succeeded
73
+ if @callbacks
74
+ while cb = @callbacks.shift
75
+ cb.call *@deferred_args
76
+ end
77
+ end
78
+ when :failed
79
+ if @errbacks
80
+ while eb = @errbacks.shift
81
+ eb.call *@deferred_args
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+ end
89
+
@@ -0,0 +1,50 @@
1
+ # $Id: eventable.rb 252 2006-09-02 19:23:20Z blackhedd $
2
+ #
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
+ # Date:: 16 July 2006
5
+ #
6
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
7
+ #
8
+ # This program is made available under the terms of the GPL version 2.
9
+ #
10
+ # See EventMachine and EventMachine::Connection for documentation and
11
+ # usage examples.
12
+ #
13
+ #----------------------------------------------------------------------------
14
+ #
15
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
16
+ #
17
+ # Gmail: garbagecat10
18
+ #
19
+ # This program is free software; you can redistribute it and/or modify
20
+ # it under the terms of the GNU General Public License as published by
21
+ # the Free Software Foundation; either version 2 of the License, or
22
+ # (at your option) any later version.
23
+ #
24
+ # This program is distributed in the hope that it will be useful,
25
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
26
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
+ # GNU General Public License for more details.
28
+ #
29
+ # You should have received a copy of the GNU General Public License
30
+ # along with this program; if not, write to the Free Software
31
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
+ #
33
+ #---------------------------------------------------------------------------
34
+ #
35
+ #
36
+
37
+
38
+ module EventMachine
39
+ module Eventable
40
+
41
+ def listen_event event_name
42
+ end
43
+
44
+ def post_event event_name, arg
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+
data/lib/eventmachine.rb CHANGED
@@ -1,6 +1,6 @@
1
- # $Id: eventmachine.rb 52 2006-05-16 01:01:46Z blackhedd $
1
+ # $Id: eventmachine.rb 283 2006-11-22 14:44:38Z blackhedd $
2
2
  #
3
- # Author:: blackhedd (gmail address: garbagecat20).
3
+ # Author:: blackhedd (gmail address: garbagecat10).
4
4
  # Date:: 8 Apr 2006
5
5
  #
6
6
  # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
@@ -34,7 +34,31 @@
34
34
  #
35
35
  #
36
36
 
37
- require 'rubyeventmachine'
37
+
38
+ #-- Select in a library based on a global variable.
39
+ case $eventmachine_library
40
+ when :pure_ruby
41
+ require 'pr_eventmachine'
42
+ when :extension
43
+ require 'rubyeventmachine'
44
+ else
45
+ # This is the case that most user code will take.
46
+ # Prefer the extension if available.
47
+ begin
48
+ require 'rubyeventmachine'
49
+ rescue LoadError
50
+ require 'pr_eventmachine'
51
+ end
52
+ end
53
+
54
+
55
+ require "eventmachine_version"
56
+ require 'em/deferrable'
57
+ require 'em/eventable'
58
+ #-- Additional requires are at the BOTTOM of this file, because they
59
+ #-- depend on stuff defined in here. Refactor that someday.
60
+
61
+
38
62
 
39
63
  # == Introduction
40
64
  # EventMachine provides a fast, lightweight framework for implementing
@@ -132,7 +156,6 @@ require 'rubyeventmachine'
132
156
  #
133
157
  module EventMachine
134
158
 
135
- VERSION = "0.5.3"
136
159
 
137
160
  # EventMachine::run initializes and runs an event loop.
138
161
  # This method only returns if user-callback code calls stop_event_loop.
@@ -187,7 +210,7 @@ module EventMachine
187
210
  # Ruby threads.
188
211
  def EventMachine::run_without_threads &block
189
212
  #EventMachine::run false, &block
190
- EventMachine::run &block
213
+ EventMachine::run(&block)
191
214
  end
192
215
 
193
216
  # EventMachine#add_timer adds a one-shot timer to the event loop.
@@ -226,12 +249,15 @@ module EventMachine
226
249
  # }
227
250
  #
228
251
  #
252
+ #--
253
+ # Changed 04Oct06: We now pass the interval as an integer number of milliseconds.
254
+ #
229
255
  def EventMachine::add_timer *args, &block
230
256
  interval = args.shift
231
257
  code = args.shift || block
232
258
  if code
233
259
  # check too many timers!
234
- s = add_oneshot_timer interval
260
+ s = add_oneshot_timer((interval * 1000).to_i)
235
261
  @timers[s] = code
236
262
  end
237
263
  end
@@ -409,7 +435,7 @@ module EventMachine
409
435
  # }
410
436
  #
411
437
  #
412
- def EventMachine::start_server server, port, handler=nil
438
+ def EventMachine::start_server server, port, handler=nil, &block
413
439
  klass = if (handler and handler.is_a?(Class))
414
440
  handler
415
441
  else
@@ -417,7 +443,19 @@ module EventMachine
417
443
  end
418
444
 
419
445
  s = start_tcp_server server, port
420
- @acceptors[s] = klass
446
+ @acceptors[s] = [klass,block]
447
+ end
448
+
449
+
450
+ def EventMachine::start_unix_domain_server filename, handler=nil, &block
451
+ klass = if (handler and handler.is_a?(Class))
452
+ handler
453
+ else
454
+ Class.new( Connection ) {handler and include handler}
455
+ end
456
+
457
+ s = start_unix_server filename
458
+ @acceptors[s] = [klass,block]
421
459
  end
422
460
 
423
461
  # EventMachine#connect initiates a TCP connection to a remote
@@ -533,6 +571,29 @@ module EventMachine
533
571
  end
534
572
 
535
573
 
574
+ #--
575
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO BE HERE IN THIS FORM, OR AT ALL.
576
+ # (03Nov06)
577
+ # Observe, the test for already-connected FAILS if we call a reconnect inside post_init,
578
+ # because we haven't set up the connection in @conns by that point.
579
+ # RESIST THE TEMPTATION to "fix" this problem by redefining the behavior of post_init.
580
+ #
581
+ # Changed 22Nov06: if called on an already-connected handler, just return the
582
+ # handler and do nothing more. Originally this condition raised an exception.
583
+ # We may want to change it yet again and call the block, if any.
584
+ #
585
+ def EventMachine::reconnect server, port, handler
586
+ raise "invalid handler" unless handler.respond_to?(:connection_completed)
587
+ #raise "still connected" if @conns.has_key?(handler.signature)
588
+ return handler if @conns.has_key?(handler.signature)
589
+ s = connect_server server, port
590
+ handler.signature = s
591
+ @conns[s] = handler
592
+ block_given? and yield handler
593
+ handler
594
+ end
595
+
596
+
536
597
  # EventMachine#open_datagram_socket is for support of UDP-based
537
598
  # protocols. Its usage is similar to that of EventMachine#start_server.
538
599
  # It takes three parameters: an IP address (which must be valid
@@ -586,6 +647,25 @@ module EventMachine
586
647
  # necessarily ones that have sent data to which you are responding),
587
648
  # then see Connection#send_datagram.
588
649
  #
650
+ #--
651
+ # Replaced the implementation on 01Oct06. Thanks to Tobias Gustafsson for pointing
652
+ # out that this originally did not take a class but only a module.
653
+ #
654
+ def self::open_datagram_socket address, port, handler=nil
655
+ klass = if (handler and handler.is_a?(Class))
656
+ handler
657
+ else
658
+ Class.new( Connection ) {handler and include handler}
659
+ end
660
+
661
+ s = open_udp_socket address, port
662
+ c = klass.new s
663
+ @conns[s] = c
664
+ block_given? and yield c
665
+ c
666
+ end
667
+ =begin
668
+ (Original, replaced 01Oct06)
589
669
  def self::open_datagram_socket address, port, handler=nil
590
670
  s = open_udp_socket address, port
591
671
  klass = Class.new( Connection ) {
@@ -596,6 +676,93 @@ module EventMachine
596
676
  block_given? and yield c
597
677
  c
598
678
  end
679
+ =end
680
+
681
+
682
+ # For advanced users. This function sets the default timer granularity, which by default is
683
+ # slightly smaller than 100 milliseconds. Call this function to set a higher or lower granularity.
684
+ # The function affects the behavior of #add_timer and #add_periodic_timer. Most applications
685
+ # will not need to call this function.
686
+ #
687
+ # The argument is a number of milliseconds. Avoid setting the quantum to very low values because
688
+ # that may reduce performance under some extreme conditions. We recommend that you not set a quantum
689
+ # lower than 10.
690
+ #
691
+ # You MUST call this function while an EventMachine loop is running (that is, after a call to
692
+ # EventMachine#run and before a subsequent call to EventMachine#stop).
693
+ #
694
+ def self::set_quantum mills
695
+ set_timer_quantum mills.to_i
696
+ end
697
+
698
+
699
+ def self::run_deferred_callbacks # :nodoc:
700
+ until @resultqueue.empty?
701
+ result,cback = @resultqueue.pop
702
+ cback.call result if cback
703
+ end
704
+ end
705
+
706
+ # #defer is for integrating blocking operations into EventMachine's control flow.
707
+ # Call #defer with one or two blocks, as shown below (the second block is <i>optional</i>):
708
+ #
709
+ # operation = proc {
710
+ # # perform a long-running operation here, such as a database query.
711
+ # "result" # as usual, the last expression evaluated in the block will be the return value.
712
+ # }
713
+ # callback = proc {|result|
714
+ # # do something with result here, such as send it back to a network client.
715
+ # }
716
+ #
717
+ # EventMachine.defer( operation, callback )
718
+ #
719
+ # The action of #defer is to take the block specified in the first parameter (the "operation")
720
+ # and schedule it for asynchronous execution on an internal thread pool maintained by EventMachine.
721
+ # When the operation completes, it will pass the result computed by the block (if any)
722
+ # back to the EventMachine reactor. Then, EventMachine calls the block specified in the
723
+ # second parameter to #defer (the "callback"), as part of its normal, synchronous
724
+ # event handling loop. The result computed by the operation block is passed as a parameter
725
+ # to the callback. You may omit the callback parameter if you don't need to execute any code
726
+ # after the operation completes.
727
+ #
728
+ # <i>Caveats:</i>
729
+ # This is a <b>provisional</b> implementation and is subject to change.
730
+ # Note carefully that the code in your deferred operation will be executed on a separate
731
+ # thread from the main EventMachine processing and all other Ruby threads that may exist in
732
+ # your program. Also, multiple deferred operations may be running at once! Therefore, you
733
+ # are responsible for ensuring that your operation code is threadsafe. [Need more explanation
734
+ # and examples.]
735
+ # Don't write a deferred operation that will block forever. If so, the current implementation will
736
+ # not detect the problem, and the thread will never be returned to the pool. EventMachine limits
737
+ # the number of threads in its pool, so if you do this enough times, your subsequent deferred
738
+ # operations won't get a chance to run. [We might put in a timer to detect this problem.]
739
+ #
740
+ def self::defer op, callback = nil
741
+ unless @threadqueue
742
+
743
+ #start_server "127.0.0.1", 29999, DeferredTrigger
744
+ #@deferred_trigger = connect "127.0.0.1", 29999
745
+
746
+ require 'thread'
747
+ @threadqueue = Queue.new
748
+ @resultqueue = Queue.new
749
+ 20.times {|ix|
750
+ Thread.new {
751
+ my_ix = ix
752
+ loop {
753
+ op,cback = @threadqueue.pop
754
+ result = op.call
755
+ @resultqueue << [result, cback]
756
+ EventMachine.signal_loopbreak
757
+ #@deferred_trigger.send_data "."
758
+ }
759
+ }
760
+ }
761
+ end
762
+
763
+ @threadqueue << [op,callback]
764
+ end
765
+
599
766
 
600
767
 
601
768
  private
@@ -613,16 +780,44 @@ module EventMachine
613
780
  raise ConnectionNotBound
614
781
  end
615
782
  when ConnectionAccepted
616
- accep = @acceptors[conn_binding] or raise NoHandlerForAcceptedConnection
783
+ accep,blk = @acceptors[conn_binding]
784
+ raise NoHandlerForAcceptedConnection unless accep
617
785
  c = accep.new data
618
786
  @conns[data] = c
787
+ blk and blk.call(c)
788
+ c # (needed?)
619
789
  when TimerFired
620
790
  t = @timers.delete( data ) or raise UnknownTimerFired
621
791
  t.call
792
+ when ConnectionCompleted
793
+ c = @conns[conn_binding] or raise ConnectionNotBound
794
+ c.connection_completed
795
+ when LoopbreakSignalled
796
+ run_deferred_callbacks
622
797
  end
623
798
  end
624
799
 
625
800
 
801
+ # Documentation stub
802
+ #--
803
+ # This is a provisional implementation of a stream-oriented file access object.
804
+ # We also experiment with wrapping up some better exception reporting.
805
+ class << self
806
+ def _open_file_for_writing filename, handler=nil
807
+ klass = if (handler and handler.is_a?(Class))
808
+ handler
809
+ else
810
+ Class.new( Connection ) {handler and include handler}
811
+ end
812
+
813
+ s = _write_file filename
814
+ c = klass.new s
815
+ @conns[s] = c
816
+ block_given? and yield c
817
+ c
818
+ end
819
+ end
820
+
626
821
 
627
822
  # EventMachine::Connection is a class that is instantiated
628
823
  # by EventMachine's processing loop whenever a new connection
@@ -650,6 +845,9 @@ module EventMachine
650
845
  #
651
846
  class Connection
652
847
 
848
+ # EXPERIMENTAL. Added the reconnect methods, which may go away.
849
+ attr_accessor :signature
850
+
653
851
  def initialize sig #:nodoc:
654
852
  @signature = sig
655
853
  post_init
@@ -770,7 +968,24 @@ class Connection
770
968
  EventMachine::send_data @signature, data, data.length
771
969
  end
772
970
 
971
+ # #connection_completed is called by the event loop when a remote TCP connection
972
+ # attempt completes successfully. You can expect to get this notification after calls
973
+ # to EventMachine#connect. Remember that EventMachine makes remote connections
974
+ # asynchronously, just as with any other kind of network event. #connection_completed
975
+ # is intended primarily to assist with network diagnostics. For normal protocol
976
+ # handling, use #post_init to perform initial work on a new connection (such as
977
+ # send an initial set of data).
978
+ # #post_init will always be called. #connection_completed will only be called in case
979
+ # of a successful completion. A connection-attempt which fails will receive a call
980
+ # to #unbind after the failure.
981
+ def connection_completed
982
+ end
773
983
 
984
+ # Call #start_tls at any point to initiate TLS encryption on connected streams.
985
+ # The method is smart enough to know whether it should perform a server-side
986
+ # or a client-side handshake. An appropriate place to call #start_tls is in
987
+ # your redefined #post_init method.
988
+ #
774
989
  def start_tls
775
990
  EventMachine::start_tls @signature
776
991
  end
@@ -800,8 +1015,58 @@ class Connection
800
1015
  end
801
1016
 
802
1017
 
1018
+ # #get_peername is used with stream-connections to obtain the identity
1019
+ # of the remotely-connected peer. If a peername is available, this method
1020
+ # returns a sockaddr structure. The method returns nil if no peername is available.
1021
+ # You can use Socket#unpack_sockaddr_in and its variants to obtain the
1022
+ # values contained in the peername structure returned from #get_peername.
1023
+ def get_peername
1024
+ EventMachine::get_peername @signature
1025
+ end
1026
+
1027
+ # comm_inactivity_timeout returns the current value (in seconds) of the inactivity-timeout
1028
+ # property of network-connection and datagram-socket objects. A nonzero value
1029
+ # indicates that the connection or socket will automatically be closed if no read or write
1030
+ # activity takes place for at least that number of seconds.
1031
+ # A zero value (the default) specifies that no automatic timeout will take place.
1032
+ def comm_inactivity_timeout
1033
+ EventMachine::get_comm_inactivity_timeout @signature
1034
+ end
1035
+
1036
+ # Alias for #set_comm_inactivity_timeout.
1037
+ def comm_inactivity_timeout= value
1038
+ self.send :set_comm_inactivity_timeout, value
1039
+ end
1040
+
1041
+ # comm_inactivity_timeout= allows you to set the inactivity-timeout property for
1042
+ # a network connection or datagram socket. Specify a non-negative numeric value in seconds.
1043
+ # If the value is greater than zero, the connection or socket will automatically be closed
1044
+ # if no read or write activity takes place for at least that number of seconds.
1045
+ # Specify a value of zero to indicate that no automatic timeout should take place.
1046
+ # Zero is the default value.
1047
+ def set_comm_inactivity_timeout value
1048
+ EventMachine::set_comm_inactivity_timeout @signature, value
1049
+ end
1050
+
1051
+ #--
1052
+ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO REMAIN SUPPORTED.
1053
+ # (03Nov06)
1054
+ def reconnect server, port
1055
+ EventMachine::reconnect server, port, self
1056
+ end
1057
+
803
1058
  end
804
1059
 
805
1060
 
806
1061
  end # module EventMachine
807
1062
 
1063
+ # At the bottom of this module, we load up protocol handlers that depend on some
1064
+ # of the classes defined here. Eventually we should refactor this out so it's
1065
+ # laid out in a more logical way.
1066
+ #
1067
+
1068
+ require 'protocols/tcptest'
1069
+ require 'protocols/httpclient'
1070
+ require 'protocols/line_and_text'
1071
+ require 'protocols/header_and_content'
1072
+