Files
EWF/library/server/httpd/concurrency/scoop/httpd_connection_handler.e
Jocelyn Fiat c132d7734b Moved httpd library from ewsgi/connectors/standalone/lib/httpd to httpd.
Reused the http_network library as well inside httpd library.
2016-10-12 22:54:21 +02:00

147 lines
3.4 KiB
Plaintext

note
description: "[
Implementation of HTTPD_CONNECTION_HANDLER_I for concurrency mode: SCOOP
]"
date: "$Date$"
revision: "$Revision$"
class
HTTPD_CONNECTION_HANDLER
inherit
HTTPD_CONNECTION_HANDLER_I
redefine
initialize
end
create
make
feature {NONE} -- Initialization
initialize
local
n: INTEGER
p: like pool
do
n := max_concurrent_connections (server).max (1) -- At least one processor!
create p.make (n)
initialize_pool (p, n)
pool := p
end
initialize_pool (p: like pool; n: INTEGER)
-- Initialize Concurrent pool of `n' potential separate connection handlers.
do
p.set_count (n)
end
feature -- Access
is_shutdown_requested: BOOLEAN
-- <Precursor>
max_concurrent_connections (a_server: like server): INTEGER
-- Max concurrent connection settings from server `a_server'.
do
Result := a_server.configuration.max_concurrent_connections
end
feature {HTTPD_SERVER_I} -- Execution
shutdown
-- <Precursor>
do
if not is_shutdown_requested then
is_shutdown_requested := True
pool_gracefull_stop (pool)
end
end
pool_gracefull_stop (p: like pool)
-- Graceful stop concurrent pool of separate connection handlers.
do
p.gracefull_stop
end
accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
-- <Precursor>
do
accept_connection_on_pool (pool, a_listening_socket) -- Wait on not pool.is_full or is_stop_requested
end
accept_connection_on_pool (a_pool: like pool; a_listening_socket: HTTPD_STREAM_SOCKET)
-- Process accept connection
-- note that the precondition matters for scoop synchronization.
require
concurrency: not a_pool.is_full or is_shutdown_requested or a_pool.stop_requested
local
cl: separate HTTPD_STREAM_SOCKET
do
debug ("dbglog")
dbglog (generator + ".ENTER accept_connection_on_pool")
end
if is_shutdown_requested then
-- Cancel
elseif attached a_pool.separate_item (factory) as h then
cl := separate_client_socket (h)
a_listening_socket.accept_to (cl)
process_handler (h)
else
check is_not_full: False end
end
debug ("dbglog")
dbglog (generator + ".LEAVE accept_connection_on_pool")
end
end
process_handler (hdl: separate HTTPD_REQUEST_HANDLER)
-- Process request handler `hdl' as soon as `hdl' is connected to accepted socket.
require
hdl.is_connected
do
hdl.safe_execute
end
feature {HTTPD_SERVER_I} -- Status report
wait_for_completion
-- Wait until Current is ready for shutdown.
do
wait_for_pool_completion (pool)
end
wait_for_pool_completion (p: like pool)
-- Wait until concurrent pool is empty and terminated.
require
p.is_empty -- SCOOP wait condition.
do
p.terminate
end
feature {NONE} -- Implementation
separate_client_socket (hdl: separate HTTPD_REQUEST_HANDLER): separate HTTPD_STREAM_SOCKET
-- Client socket for request handler `hdl'.
do
Result := hdl.client_socket
end
pool: separate CONCURRENT_POOL [HTTPD_REQUEST_HANDLER]
-- Pool of separate connection handlers.
invariant
pool_attached: pool /= Void
note
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end