We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Various JRuby compatibility fixes.
Hongli Lai (Phusion) (author)
Fri Nov 21 06:05:06 -0800 2008
commit  9b459571069977c8dd3bf0e7c19110968754e7bb
tree    68adaea0e47116c566038c8cdf06fd37f84876b1
parent  13982fb2444a7c74f16a9007d2048cfbe0b6bd50
...
20
21
22
23
24
25
26
...
82
83
84
85
 
86
87
 
88
89
90
...
133
134
135
136
 
137
138
139
...
177
178
179
180
181
 
 
182
183
184
...
252
253
254
 
 
 
 
 
255
256
 
257
258
259
...
267
268
269
270
 
271
272
273
...
281
282
283
 
 
284
285
286
 
 
287
288
289
 
 
290
291
292
...
325
326
327
328
 
329
330
331
...
20
21
22
 
23
24
25
...
81
82
83
 
84
85
 
86
87
88
89
...
132
133
134
 
135
136
137
138
...
176
177
178
 
 
179
180
181
182
183
...
251
252
253
254
255
256
257
258
259
 
260
261
262
263
...
271
272
273
 
274
275
276
277
...
285
286
287
288
289
290
291
 
292
293
294
295
 
296
297
298
299
300
...
333
334
335
 
336
337
338
339
0
@@ -20,7 +20,6 @@ require 'socket'
0
 require 'fcntl'
0
 require 'passenger/message_channel'
0
 require 'passenger/utils'
0
-require 'passenger/native_support'
0
 module Passenger
0
 
0
 # The request handler is the layer which connects Apache with the underlying application's
0
@@ -82,9 +81,9 @@ module Passenger
0
 # and sends it to the request handler.
0
 class AbstractRequestHandler
0
   # Signal which will cause the Rails application to exit immediately.
0
- HARD_TERMINATION_SIGNAL = "SIGTERM"
0
+ HARD_TERMINATION_SIGNAL = "TERM"
0
   # Signal which will cause the Rails application to exit as soon as it's done processing a request.
0
- SOFT_TERMINATION_SIGNAL = "SIGUSR1"
0
+ SOFT_TERMINATION_SIGNAL = "USR1"
0
   BACKLOG_SIZE = 50
0
   MAX_HEADER_SIZE = 128 * 1024
0
   
0
@@ -133,7 +132,7 @@ class AbstractRequestHandler
0
   def initialize(owner_pipe, options = {})
0
     @socket_type = 'unix'
0
     create_unix_socket_on_filesystem
0
- @socket.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
0
+ @socket.close_on_exec!
0
     @owner_pipe = owner_pipe
0
     @previous_signal_handlers = {}
0
     @main_loop_thread_lock = Mutex.new
0
@@ -177,8 +176,8 @@ class AbstractRequestHandler
0
     reset_signal_handlers
0
     begin
0
       @graceful_termination_pipe = IO.pipe
0
- @graceful_termination_pipe[0].fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
0
- @graceful_termination_pipe[1].fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
0
+ @graceful_termination_pipe[0].close_on_exec!
0
+ @graceful_termination_pipe[1].close_on_exec!
0
       
0
       @main_loop_thread_lock.synchronize do
0
         @main_loop_running = true
0
@@ -252,8 +251,13 @@ private
0
     done = false
0
     while !done
0
       begin
0
+ if defined?(NativeSupport)
0
+ unix_path_max = NativeSupport::UNIX_PATH_MAX
0
+ else
0
+ unix_path_max = 100
0
+ end
0
         @socket_name = "#{passenger_tmpdir}/passenger_backend.#{generate_random_id(:base64)}"
0
- @socket_name = @socket_name.slice(0, NativeSupport::UNIX_PATH_MAX - 1)
0
+ @socket_name = @socket_name.slice(0, unix_path_max - 1)
0
         @socket = UNIXServer.new(@socket_name)
0
         File.chmod(0600, @socket_name)
0
         done = true
0
@@ -267,7 +271,7 @@ private
0
   # special handlers for a few signals. The previous signal handlers
0
   # will be put back by calling revert_signal_handlers.
0
   def reset_signal_handlers
0
- Signal.list.each_key do |signal|
0
+ Signal.list_trappable.each_key do |signal|
0
       begin
0
         prev_handler = trap(signal, DEFAULT)
0
         if prev_handler != DEFAULT
0
@@ -281,12 +285,16 @@ private
0
   end
0
   
0
   def install_useful_signal_handlers
0
+ trappable_signals = Signal.list_trappable
0
+
0
     trap(SOFT_TERMINATION_SIGNAL) do
0
       @graceful_termination_pipe[1].close rescue nil
0
- end
0
+ end if trappable_signals.has_key?(SOFT_TERMINATION_SIGNAL)
0
+
0
     trap('ABRT') do
0
       raise SignalException, "SIGABRT"
0
- end
0
+ end if trappable_signals.has_key?('ABRT')
0
+
0
     trap('QUIT') do
0
       if Kernel.respond_to?(:caller_for_all_threads)
0
         output = "========== Process #{Process.pid}: backtrace dump ==========\n"
0
@@ -325,7 +333,7 @@ private
0
     ios = select([@socket, @owner_pipe, @graceful_termination_pipe[0]]).first
0
     if ios.include?(@socket)
0
       client = @socket.accept
0
- client.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
0
+ client.close_on_exec!
0
       
0
       # The real input stream is not seekable (calling _seek_
0
       # or _rewind_ on it will raise an exception). But some
...
140
141
142
 
143
144
145
...
140
141
142
143
144
145
146
0
@@ -140,6 +140,7 @@ class MessageChannel
0
       end
0
       buffer = ''
0
       while buffer.size < size
0
+ temp = '' # JRuby doesn't clear the buffer. TODO: remove this when JRuby has been fixed.
0
         buffer << @io.readpartial(size - buffer.size, temp)
0
       end
0
       return buffer
...
23
24
25
 
26
27
28
...
425
426
427
428
429
430
431
432
433
 
 
 
 
 
 
 
434
435
436
437
438
439
440
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
442
443
444
445
446
447
448
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
450
451
...
23
24
25
26
27
28
29
...
426
427
428
 
 
 
 
 
 
429
430
431
432
433
434
435
436
 
 
 
 
 
 
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
 
 
 
 
 
 
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
0
@@ -23,6 +23,7 @@ if RUBY_PLATFORM != "java" && RUBY_VERSION < "1.8.7"
0
 end
0
 require 'pathname'
0
 require 'etc'
0
+require 'fcntl'
0
 require 'tempfile'
0
 require 'passenger/exceptions'
0
 if RUBY_PLATFORM != "java"
0
@@ -425,27 +426,64 @@ class ConditionVariable
0
 end
0
 
0
 class IO
0
- # ApplicationSpawner/FrameworkSpawner might temporarily undefine
0
- # the 'Passenger' module in order to avoid namespace collissions
0
- # with the spawned application. So we save the NativeSupport
0
- # module in a constant so that we can access it whether
0
- # our 'Passenger' module is defined or not.
0
- NATIVE_SUPPORT = Passenger::NativeSupport
0
+ if defined?(Passenger::NativeSupport)
0
+ # ApplicationSpawner/FrameworkSpawner might temporarily undefine
0
+ # the 'Passenger' module in order to avoid namespace collissions
0
+ # with the spawned application. So we save the NativeSupport
0
+ # module in a constant so that we can access it whether
0
+ # our 'Passenger' module is defined or not.
0
+ NATIVE_SUPPORT = Passenger::NativeSupport
0
 
0
- # Send an IO object (i.e. a file descriptor) over this IO channel.
0
- # This only works if this IO channel is a Unix socket.
0
- #
0
- # Raises SystemCallError if something went wrong.
0
- def send_io(io)
0
- NATIVE_SUPPORT.send_fd(self.fileno, io.fileno)
0
+ # Send an IO object (i.e. a file descriptor) over this IO channel.
0
+ # This only works if this IO channel is a Unix socket.
0
+ #
0
+ # Raises SystemCallError if something went wrong.
0
+ def send_io(io)
0
+ NATIVE_SUPPORT.send_fd(self.fileno, io.fileno)
0
+ end
0
+
0
+ # Receive an IO object (i.e. a file descriptor) from this IO channel.
0
+ # This only works if this IO channel is a Unix socket.
0
+ #
0
+ # Raises SystemCallError if something went wrong.
0
+ def recv_io
0
+ return IO.new(NATIVE_SUPPORT.recv_fd(self.fileno))
0
+ end
0
   end
0
   
0
- # Receive an IO object (i.e. a file descriptor) from this IO channel.
0
- # This only works if this IO channel is a Unix socket.
0
- #
0
- # Raises SystemCallError if something went wrong.
0
- def recv_io
0
- return IO.new(NATIVE_SUPPORT.recv_fd(self.fileno))
0
+ def close_on_exec!
0
+ if defined?(Fcntl::F_SETFD)
0
+ fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
0
+ end
0
+ end
0
+end
0
+
0
+module Signal
0
+ # Like Signal.list, but only returns signals that we can actually trap.
0
+ def self.list_trappable
0
+ ruby_engine = defined?(RUBY_ENGINE) ? RUBY_ENGINE : "mri"
0
+ case ruby_engine
0
+ when "mri"
0
+ if RUBY_VERSION >= '1.9.0'
0
+ return Signal.list
0
+ else
0
+ result = Signal.list
0
+ result.delete("ALRM")
0
+ return result
0
+ end
0
+ when "jruby"
0
+ result = Signal.list
0
+ result.delete("QUIT")
0
+ result.delete("ILL")
0
+ result.delete("FPE")
0
+ result.delete("KILL")
0
+ result.delete("SEGV")
0
+ result.delete("STOP")
0
+ result.delete("USR1")
0
+ return result
0
+ else
0
+ return Signal.list
0
+ end
0
   end
0
 end
0
 

Comments

    No one has commented yet.