lib/eventmachine.rb in eventmachine-win32-0.7.0 vs lib/eventmachine.rb in eventmachine-win32-0.7.2

- old
+ new

@@ -1,43 +1,33 @@ -# $Id: eventmachine.rb 283 2006-11-22 14:44:38Z blackhedd $ +# $Id: eventmachine.rb 319 2007-05-22 22:11:18Z blackhedd $ # -# Author:: blackhedd (gmail address: garbagecat10). +# Author:: Francis Cianfrocca (gmail: blackhedd) +# Homepage:: http://rubyeventmachine.com # Date:: 8 Apr 2006 # -# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. -# -# This program is made available under the terms of the GPL version 2. -# # See EventMachine and EventMachine::Connection for documentation and # usage examples. # #---------------------------------------------------------------------------- # -# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. -# -# Gmail: garbagecat10 -# +# Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved. +# Gmail: blackhedd +# # This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# it under the terms of either: 1) the GNU General Public License +# as published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version; or 2) Ruby's License. +# +# See the file COPYING for complete licensing information. # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# #--------------------------------------------------------------------------- # # #-- Select in a library based on a global variable. +$eventmachine_library ||= nil case $eventmachine_library when :pure_ruby require 'pr_eventmachine' when :extension require 'rubyeventmachine' @@ -52,10 +42,11 @@ end require "eventmachine_version" require 'em/deferrable' +require 'em/future' require 'em/eventable' #-- Additional requires are at the BOTTOM of this file, because they #-- depend on stuff defined in here. Refactor that someday. @@ -155,55 +146,64 @@ # # module EventMachine - # EventMachine::run initializes and runs an event loop. - # This method only returns if user-callback code calls stop_event_loop. - # Use the supplied block to define your clients and servers. - # The block is called by EventMachine::run immediately after initializing - # its internal event loop but <i>before</i> running the loop. - # Therefore this block is the right place to call start_server if you - # want to accept connections from remote clients. - # - # For programs that are structured as servers, it's usually appropriate - # to start an event loop by calling EventMachine::run, and let it - # run forever. It's also possible to use EventMachine::run to make a single - # client-connection to a remote server, process the data flow from that - # single connection, and then call stop_event_loop to force EventMachine::run - # to return. Your program will then continue from the point immediately - # following the call to EventMachine::run. - # - # You can of course do both client and servers simultaneously in the same program. - # One of the strengths of the event-driven programming model is that the - # handling of network events on many different connections will be interleaved, - # and scheduled according to the actual events themselves. This maximizes - # efficiency. - # - # === Server usage example - # - # See the text at the top of this file for an example of an echo server. - # - # === Client usage example - # - # See the description of stop_event_loop for an extremely simple client example. - # - #-- - # Obsoleted the use_threads mechanism. - # - def EventMachine::run &block - #def EventMachine::run use_threads = true, &block - @conns = {} - @acceptors = {} - @timers = {} - initialize_event_machine - block and add_timer 0, block - #use_threads ? run_machine : run_machine_without_threads - run_machine - release_machine - end + # EventMachine::run initializes and runs an event loop. + # This method only returns if user-callback code calls stop_event_loop. + # Use the supplied block to define your clients and servers. + # The block is called by EventMachine::run immediately after initializing + # its internal event loop but <i>before</i> running the loop. + # Therefore this block is the right place to call start_server if you + # want to accept connections from remote clients. + # + # For programs that are structured as servers, it's usually appropriate + # to start an event loop by calling EventMachine::run, and let it + # run forever. It's also possible to use EventMachine::run to make a single + # client-connection to a remote server, process the data flow from that + # single connection, and then call stop_event_loop to force EventMachine::run + # to return. Your program will then continue from the point immediately + # following the call to EventMachine::run. + # + # You can of course do both client and servers simultaneously in the same program. + # One of the strengths of the event-driven programming model is that the + # handling of network events on many different connections will be interleaved, + # and scheduled according to the actual events themselves. This maximizes + # efficiency. + # + # === Server usage example + # + # See the text at the top of this file for an example of an echo server. + # + # === Client usage example + # + # See the description of stop_event_loop for an extremely simple client example. + # + #-- + # Obsoleted the use_threads mechanism. + # 25Nov06: Added the begin/ensure block. We need to be sure that release_machine + # gets called even if an exception gets thrown within any of the user code + # that the event loop runs. The best way to see this is to run a unit + # test with two functions, each of which calls EventMachine#run and each of + # which throws something inside of #run. Without the ensure, the second test + # will start without release_machine being called and will immediately throw + # a C++ runtime error. + # + def EventMachine::run &block + @conns = {} + @acceptors = {} + @timers = {} + begin + initialize_event_machine + block and add_timer 0, block + run_machine + ensure + release_machine + end + end + # +deprecated+ #-- # EventMachine#run_without_threads is semantically identical # to EventMachine#run, but it runs somewhat faster. # However, it must not be used in applications that spin @@ -257,10 +257,11 @@ code = args.shift || block if code # check too many timers! s = add_oneshot_timer((interval * 1000).to_i) @timers[s] = code + s end end # EventMachine#add_periodic_timer adds a periodic timer to the event loop. # It takes the same parameters as the one-shot timer method, EventMachine#add_timer. @@ -288,11 +289,18 @@ } add_timer interval, block_1 end end + #-- + # + def EventMachine::cancel_timer signature + @timers[signature] = proc{} if @timers.has_key?(signature) + end + private_class_method :cancel_timer + # stop_event_loop may called from within a callback method # while EventMachine's processing loop is running. # It causes the processing loop to stop executing, which # will cause all open connections and accepting servers # to be run down and closed. <i>Callbacks for connection-termination @@ -592,10 +600,41 @@ block_given? and yield handler handler end + + + # Make a connection to a Unix-domain socket. This is not implemented on Windows platforms. + # The parameter socketname is a String which identifies the Unix-domain socket you want + # to connect to. socketname is the name of a file on your local system, and in most cases + # is a fully-qualified path name. Make sure that your process has enough local permissions + # to open the Unix-domain socket. + # See also the documentation for #connect_server. This method behaves like #connect_server + # in all respects except for the fact that it connects to a local Unix-domain + # socket rather than a TCP socket. + # NOTE: this functionality will soon be subsumed into the #connect method. This method + # will still be supported as an alias. + #-- + # For making connections to Unix-domain sockets. + # Eventually this has to get properly documented and unified with the TCP-connect methods. + # Note how nearly identical this is to EventMachine#connect + def EventMachine::connect_unix_domain socketname, handler=nil + klass = if (handler and handler.is_a?(Class)) + handler + else + Class.new( Connection ) {handler and include handler} + end + + s = connect_unix_server socketname + c = klass.new s + @conns[s] = c + block_given? and yield c + c + end + + # EventMachine#open_datagram_socket is for support of UDP-based # protocols. Its usage is similar to that of EventMachine#start_server. # It takes three parameters: an IP address (which must be valid # on the machine which executes the method), a port number, # and an optional Module name which will handle the data. @@ -761,10 +800,22 @@ end @threadqueue << [op,callback] end + # A wrapper over the setuid system call. Particularly useful when opening a network + # server on a privileged port because you can use this call to drop privileges + # after opening the port. + # This method has no effective implementation on Windows or in the pure-Ruby + # implementation of EventMachine. + # Call #set_effective_user by passing it a string containing the effective name + # of the user whose privilege-level your process should attain. + # This method is intended for use in enforcing security requirements, consequently + # it will throw a fatal error and end your program if it fails. + def self::set_effective_user username + EventMachine::setuid_string username + end private def EventMachine::event_callback conn_binding, opcode, data case opcode @@ -1052,9 +1103,48 @@ # EXPERIMENTAL. DO NOT RELY ON THIS METHOD TO REMAIN SUPPORTED. # (03Nov06) def reconnect server, port EventMachine::reconnect server, port, self end + + + + + # + # + # + class EventMachine::PeriodicTimer + def initialize *args, &block + @interval = args.shift + @code = args.shift || block + schedule + end + def schedule + EventMachine::add_timer @interval, proc {self.fire} + end + def fire + @code.call + schedule unless @cancelled + end + def cancel + @cancelled = true + end + end + + # + # + # + class EventMachine::Timer + def initialize *args, &block + @signature = EventMachine::add_timer(*args, &block) + end + def cancel + EventMachine.send :cancel_timer, @signature + end + end + + + end end # module EventMachine