/usr/lib/ruby/vendor_ruby/jeventmachine.rb is in ruby-eventmachine 0.12.10-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | #--
#
# Author:: Francis Cianfrocca (gmail: blackhedd)
# Homepage:: http://rubyeventmachine.com
# Date:: 8 Apr 2006
#
# See EventMachine and EventMachine::Connection for documentation and
# usage examples.
#
#----------------------------------------------------------------------------
#
# 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 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 module provides "glue" for the Java version of the EventMachine reactor core.
# For C++ EventMachines, the analogous functionality is found in ext/rubymain.cpp,
# which is a garden-variety Ruby-extension glue module.
require 'java'
require 'em_reactor'
require 'socket'
java_import java.io.FileDescriptor
java_import java.nio.channels.SocketChannel
java_import java.lang.reflect.Field
module JavaFields
def set_field(key, value)
field = getClass.getDeclaredField(key)
field.setAccessible(true)
if field.getType.toString == 'int'
field.setInt(self, value)
else
field.set(self, value)
end
end
def get_field(key)
field = getClass.getDeclaredField(key)
field.setAccessible(true)
field.get(self)
end
end
FileDescriptor.send :include, JavaFields
SocketChannel.send :include, JavaFields
module EventMachine
# TODO: These event numbers are defined in way too many places.
# DRY them up.
TimerFired = 100
ConnectionData = 101
ConnectionUnbound = 102
ConnectionAccepted = 103
ConnectionCompleted = 104
LoopbreakSignalled = 105
ConnectionNotifyReadable = 106
ConnectionNotifyWritable = 107
SslHandshakeCompleted = 108
# Exceptions that are defined in rubymain.cpp
class ConnectionNotBound < RuntimeError; end
class UnknownTimerFired < RuntimeError; end
class Unsupported < RuntimeError; end
# This thunk class used to be called EM, but that caused conflicts with
# the alias "EM" for module EventMachine. (FC, 20Jun08)
class JEM < com.rubyeventmachine.EmReactor
def eventCallback a1, a2, a3, a4
s = String.from_java_bytes(a3.array[a3.position...a3.limit]) if a3
EventMachine::event_callback a1, a2, s || a4
nil
end
end
# class Connection < com.rubyeventmachine.Connection
# def associate_callback_target sig
# # No-op for the time being.
# end
# end
def self.initialize_event_machine
@em = JEM.new
end
def self.release_machine
@em = nil
end
def self.add_oneshot_timer interval
@em.installOneshotTimer interval
end
def self.run_machine
@em.run
end
def self.stop
@em.stop
end
def self.start_tcp_server server, port
@em.startTcpServer server, port
end
def self.stop_tcp_server sig
@em.stopTcpServer sig
end
def self.start_unix_server filename
# TEMPORARILY unsupported until someone figures out how to do it.
raise "unsupported on this platform"
end
def self.send_data sig, data, length
@em.sendData sig, data.to_java_bytes
end
def self.send_datagram sig, data, length, address, port
@em.sendDatagram sig, data, length, address, port
end
def self.connect_server server, port
bind_connect_server nil, nil, server, port
end
def self.bind_connect_server bind_addr, bind_port, server, port
@em.connectTcpServer bind_addr, bind_port.to_i, server, port
end
def self.close_connection sig, after_writing
@em.closeConnection sig, after_writing
end
def self.set_comm_inactivity_timeout sig, interval
@em.setCommInactivityTimeout sig, interval
end
def self.start_tls sig
@em.startTls sig
end
def self.ssl?
false
end
def self.signal_loopbreak
@em.signalLoopbreak
end
def self.set_timer_quantum q
@em.setTimerQuantum q
end
def self.epoll
# Epoll is a no-op for Java.
# The latest Java versions run epoll when possible in NIO.
end
def self.epoll= val
end
def self.kqueue
end
def self.kqueue= val
end
def self.epoll?
false
end
def self.kqueue?
false
end
def self.set_rlimit_nofile n_descriptors
# Currently a no-op for Java.
end
def self.open_udp_socket server, port
@em.openUdpSocket server, port
end
def self.invoke_popen cmd
# TEMPORARILY unsupported until someone figures out how to do it.
raise "unsupported on this platform"
end
def self.read_keyboard
# TEMPORARILY unsupported until someone figures out how to do it.
raise "temporarily unsupported on this platform"
end
def self.set_max_timer_count num
# harmless no-op in Java. There's no built-in timer limit.
@max_timer_count = num
end
def self.get_max_timer_count
# harmless no-op in Java. There's no built-in timer limit.
@max_timer_count || 100_000
end
def self.library_type
:java
end
def self.get_peername sig
if peer = @em.getPeerName(sig)
Socket.pack_sockaddr_in *peer
end
end
def self.attach_fd fileno, watch_mode
# 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and
# we would need some logic to make sure detach_fd below didn't clobber it. For now, we just always make a new
# SocketChannel for the underlying file descriptor
# if fileno.java_kind_of? SocketChannel
# ch = fileno
# ch.configureBlocking(false)
# fileno = nil
# elsif fileno.java_kind_of? java.nio.channels.Channel
if fileno.java_kind_of? java.nio.channels.Channel
field = fileno.getClass.getDeclaredField('fdVal')
field.setAccessible(true)
fileno = field.get(fileno)
else
raise ArgumentError, 'attach_fd requires Java Channel or POSIX fileno' unless fileno.is_a? Fixnum
end
if fileno == 0
raise "can't open STDIN as selectable in Java =("
elsif fileno.is_a? Fixnum
# 8Aug09: The following code is specific to the sun jvm's SocketChannelImpl. Is there a cross-platform
# way of implementing this? If so, also remember to update EventableSocketChannel#close and #cleanup
fd = FileDescriptor.new
fd.set_field 'fd', fileno
ch = SocketChannel.open
ch.configureBlocking(false)
ch.kill
ch.set_field 'fd', fd
ch.set_field 'fdVal', fileno
ch.set_field 'state', ch.get_field('ST_CONNECTED')
end
@em.attachChannel(ch,watch_mode)
end
def self.detach_fd sig
if ch = @em.detachChannel(sig)
ch.get_field 'fdVal'
end
end
def self.set_notify_readable sig, mode
@em.setNotifyReadable(sig, mode)
end
def self.set_notify_writable sig, mode
@em.setNotifyWritable(sig, mode)
end
def self.is_notify_readable sig
@em.isNotifyReadable(sig)
end
def self.is_notify_writable sig
@em.isNotifyWritable(sig)
end
def self.get_connection_count
@em.getConnectionCount
end
class Connection
def associate_callback_target sig
# No-op for the time being
end
end
end
|