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