Class: PhusionPassenger::RequestHandler::ThreadHandler

Inherits:
Object
  • Object
show all
Includes:
DebugLogging, Utils
Defined in:
lib/phusion_passenger/request_handler/thread_handler.rb

Overview

This class encapsulates the logic of a single RequestHandler thread.

Defined Under Namespace

Classes: Interrupted

Constant Summary collapse

REQUEST_METHOD =
'REQUEST_METHOD'.freeze
PING =
'PING'.freeze
OOBW =
'OOBW'.freeze
PASSENGER_CONNECT_PASSWORD =
'PASSENGER_CONNECT_PASSWORD'.freeze
CONTENT_LENGTH =
'CONTENT_LENGTH'.freeze
TRANSFER_ENCODING =
'TRANSFER_ENCODING'.freeze
MAX_HEADER_SIZE =
128 * 1024
OBJECT_SPACE_SUPPORTS_LIVE_OBJECTS =
ObjectSpace.respond_to?(:live_objects)
OBJECT_SPACE_SUPPORTS_ALLOCATED_OBJECTS =
ObjectSpace.respond_to?(:allocated_objects)
OBJECT_SPACE_SUPPORTS_COUNT_OBJECTS =
ObjectSpace.respond_to?(:count_objects)
GC_SUPPORTS_TIME =
GC.respond_to?(:time)
GC_SUPPORTS_CLEAR_STATS =
GC.respond_to?(:clear_stats)

Constants included from Utils

Utils::NULL

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#connect_to_server, #generate_random_id, #get_socket_address_type, #global_backtrace_report, included, #install_options_as_ivars, #local_socket_address?, mktmpdir, #print_exception, #process_is_alive?, #require_option, #split_by_null_into_hash

Methods included from DebugLogging

_log_device, debug, error, included, log_file=, log_level, log_level=, stderr_evaluator=, trace, warn

Constructor Details

#initialize(request_handler, options = {}) ⇒ ThreadHandler

Returns a new instance of ThreadHandler.



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
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 62

def initialize(request_handler, options = {})
	@request_handler   = request_handler
	@server_socket     = Utils.require_option(options, :server_socket)
	@socket_name       = Utils.require_option(options, :socket_name)
	@protocol          = Utils.require_option(options, :protocol)
	@app_group_name    = Utils.require_option(options, :app_group_name)
	Utils.install_options_as_ivars(self, options,
		:app,
		:analytics_logger,
		:connect_password
	)

	@stats_mutex   = Mutex.new
	@interruptable = false
	@iteration     = 0

	if @protocol == :session
		metaclass = class << self; self; end
		metaclass.class_eval do
			alias parse_request parse_session_request
		end
	elsif @protocol == :http
		metaclass = class << self; self; end
		metaclass.class_eval do
			alias parse_request parse_http_request
		end
	else
		raise ArgumentError, "Unknown protocol specified"
	end
end

Instance Attribute Details

#interruptableObject (readonly)

Returns the value of attribute interruptable.



59
60
61
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 59

def interruptable
  @interruptable
end

#iterationObject (readonly)

Returns the value of attribute iteration.



60
61
62
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 60

def iteration
  @iteration
end

#stats_mutexObject (readonly)

Returns the value of attribute stats_mutex.



58
59
60
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 58

def stats_mutex
  @stats_mutex
end

#threadObject (readonly)

Returns the value of attribute thread.



57
58
59
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 57

def thread
  @thread
end

Instance Method Details

#installObject



93
94
95
96
97
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 93

def install
	@thread = Thread.current
	Thread.current[:passenger_thread_handler] = self
	PhusionPassenger.call_event(:starting_request_handler_thread)
end

#main_loop(finish_callback) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/phusion_passenger/request_handler/thread_handler.rb', line 99

def main_loop(finish_callback)
	socket_wrapper = Utils::UnseekableSocket.new
	channel        = MessageChannel.new
	buffer         = ''
	buffer.force_encoding('binary') if buffer.respond_to?(:force_encoding)
	
	begin
		finish_callback.call
		while true
			hijacked = accept_and_process_next_request(socket_wrapper, channel, buffer)
			socket_wrapper = Utils::UnseekableSocket.new if hijacked
		end
	rescue Interrupted
		# Do nothing.
	end
	debug("Thread handler main loop exited normally")
ensure
	@stats_mutex.synchronize { @interruptable = true }
end