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 -- 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 -- 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: HTTP_STREAM_SOCKET) -- 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: HTTP_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 HTTP_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 HTTP_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