First attempt to use `{NETWORK_STREAM_SOCKET}.accept_to'

This commit is contained in:
2015-03-17 09:48:11 +01:00
parent 7f27a6c797
commit 557b11f4e6
7 changed files with 88 additions and 101 deletions

View File

@@ -57,45 +57,33 @@ feature {HTTPD_SERVER_I} -- Execution
p.gracefull_stop p.gracefull_stop
end end
process_incoming_connection (a_socket: HTTPD_STREAM_SOCKET) accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
-- <Precursor>
do do
debug ("dbglog") accept_connection_on_pool (a_listening_socket, pool) -- Wait on not pool.is_full or is_stop_requested
dbglog (generator + ".before process_incoming_connection {"+ a_socket.descriptor.out +"} -- SCOOP WAIT!")
end
-- if is_shutdown_requested then
-- a_socket.cleanup
-- else
process_connection_on_pool (a_socket, pool) -- Wait on not pool.is_full or is_stop_requested
-- end
debug ("dbglog")
dbglog (generator + ".after process_incoming_connection {"+ a_socket.descriptor.out +"}")
end
end end
process_connection_on_pool (a_socket: HTTPD_STREAM_SOCKET; a_pool: like pool) accept_connection_on_pool (a_listening_socket: HTTPD_STREAM_SOCKET; a_pool: like pool)
-- Process incoming connection -- Process accept connection
-- note that the precondition matters for scoop synchronization. -- note that the precondition matters for scoop synchronization.
require require
concurrency: not a_pool.is_full or is_shutdown_requested or a_pool.stop_requested concurrency: not a_pool.is_full or is_shutdown_requested or a_pool.stop_requested
do do
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".ENTER process_connection {"+ a_socket.descriptor.out +"}") dbglog (generator + ".ENTER accept_connection_on_pool")
end end
if is_shutdown_requested then if is_shutdown_requested then
a_socket.cleanup -- Cancel
elseif attached a_pool.separate_item (factory) as h then elseif attached a_pool.separate_item (factory) as h then
process_request_handler (h, a_socket) process_request_handler_on_accept (h, a_listening_socket)
else else
check is_not_full: False end check is_not_full: False end
a_socket.cleanup
end end
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".LEAVE process_connection {"+ a_socket.descriptor.out +"}") dbglog (generator + ".LEAVE accept_connection_on_pool")
end end
end end
process_request_handler (hdl: separate HTTPD_REQUEST_HANDLER; a_socket: HTTPD_STREAM_SOCKET) process_request_handler_on_accept (hdl: separate HTTPD_REQUEST_HANDLER; a_listening_socket: HTTPD_STREAM_SOCKET)
require require
not hdl.has_error not hdl.has_error
do do
@@ -103,20 +91,21 @@ feature {HTTPD_SERVER_I} -- Execution
--| also handle permanent connection...? --| also handle permanent connection...?
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".ENTER process_request_handler {"+ a_socket.descriptor.out +"}") dbglog (generator + ".ENTER process_request_handler_on_accept")
end end
hdl.set_client_socket (a_socket) hdl.accept_from_listening_socket (a_listening_socket)
if hdl.has_error then if hdl.has_error then
log ("Internal error (set_client_socket failed)") log ("Internal error (accept_from_listening_socket failed)")
else else
-- hdl.set_logger (server) -- hdl.set_logger (server)
if attached hdl.separate_execution as l_result then if attached hdl.separate_execution as l_result then
end end
hdl.separate_release hdl.separate_release
end end
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".LEAVE process_request_handler {"+ a_socket.descriptor.out +"}") dbglog (generator + ".LEAVE process_request_handler_on_accept")
end end
rescue rescue
log ("Releasing handler after exception!") log ("Releasing handler after exception!")

View File

@@ -12,9 +12,7 @@ deferred class
inherit inherit
HTTPD_REQUEST_HANDLER_I HTTPD_REQUEST_HANDLER_I
redefine redefine
-- set_client_socket, release
release,
reset
end end
CONCURRENT_POOL_ITEM CONCURRENT_POOL_ITEM
@@ -22,42 +20,23 @@ inherit
release as release_pool_item release as release_pool_item
end end
feature {NONE} -- Initialization
reset
do
if attached client_socket_source as l_sock then
cleanup_separate_socket (l_sock)
end
Precursor
client_socket_source := Void
end
cleanup_separate_socket (a_socket: attached like client_socket_source)
do
a_socket.cleanup
end
feature -- Access
client_socket: detachable HTTPD_STREAM_SOCKET
client_socket_source: detachable separate HTTPD_STREAM_SOCKET
-- Associated original client socket
-- kept to avoid being closed when disposed,
-- and thus avoid closing related `client_socket'.
feature -- Change feature -- Change
set_client_socket (a_socket: separate HTTPD_STREAM_SOCKET) accept_from_listening_socket (a_listening_socket: separate HTTPD_STREAM_SOCKET)
local local
retried: BOOLEAN retried: BOOLEAN
s: like client_socket
do do
if retried then if retried then
has_error := True has_error := True
else else
create client_socket.make_from_separate (a_socket) create s.make_empty
client_socket_source := a_socket client_socket := s
a_listening_socket.accept_to (s)
if not s.is_created then
has_error := True
client_socket := Void
end
end end
rescue rescue
retried := True retried := True
@@ -99,7 +78,7 @@ feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
end end
note note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -38,7 +38,7 @@ feature {NONE} -- Access
feature {HTTPD_SERVER_I} -- Execution feature {HTTPD_SERVER_I} -- Execution
process_incoming_connection (a_socket: HTTPD_STREAM_SOCKET) accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
deferred deferred
end end
@@ -72,7 +72,7 @@ feature {NONE} -- Output
end end
note note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -23,21 +23,22 @@ feature {NONE} -- Initialization
version := Void version := Void
remote_info := Void remote_info := Void
-- if attached client_socket as l_sock then if attached client_socket as l_sock then
-- l_sock.cleanup l_sock.cleanup
-- end end
-- client_socket := Void client_socket := Void
-- FIXME: optimize to just wipe_out if needed -- FIXME: optimize to just wipe_out if needed
create method.make_empty create method.make_empty
create uri.make_empty create uri.make_empty
create request_header.make_empty create request_header.make_empty
create request_header_map.make (10) create request_header_map.make (10)
end end
feature -- Access feature -- Access
-- client_socket: detachable TCP_STREAM_SOCKET client_socket: detachable HTTPD_STREAM_SOCKET
request_header: STRING request_header: STRING
-- Header' source -- Header' source
@@ -69,16 +70,6 @@ feature -- Status report
feature -- Change feature -- Change
-- set_client_socket (a_socket: separate TCP_STREAM_SOCKET)
-- require
-- socket_attached: a_socket /= Void
-- socket_valid: a_socket.is_open_read and then a_socket.is_open_write
-- a_http_socket: not a_socket.is_closed
-- deferred
-- ensure
-- attached client_socket as s implies s.descriptor = a_socket.descriptor
-- end
set_is_verbose (b: BOOLEAN) set_is_verbose (b: BOOLEAN)
do do
is_verbose := b is_verbose := b
@@ -265,7 +256,7 @@ invariant
request_header_attached: request_header /= Void request_header_attached: request_header /= Void
note note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -126,8 +126,7 @@ feature -- Listening
-- Creates a socket and connects to the http server. -- Creates a socket and connects to the http server.
-- `a_server': The main server object -- `a_server': The main server object
local local
l_listening_socket, l_listening_socket: detachable HTTPD_STREAM_SOCKET
l_accepted_socket: detachable HTTPD_STREAM_SOCKET
l_http_port: INTEGER l_http_port: INTEGER
l_connection_handler: HTTPD_CONNECTION_HANDLER l_connection_handler: HTTPD_CONNECTION_HANDLER
do do
@@ -164,23 +163,18 @@ feature -- Listening
until until
is_shutdown_requested is_shutdown_requested
loop loop
l_listening_socket.accept
if not is_shutdown_requested then
l_accepted_socket := l_listening_socket.accepted
if l_accepted_socket /= Void then
request_counter := request_counter + 1 request_counter := request_counter + 1
if is_verbose then if is_verbose then
log ("#" + request_counter.out + "# Incoming connection...(socket:" + l_accepted_socket.descriptor.out + ")") log ("#" + request_counter.out + "# Waiting connection...(listening socket:" + l_listening_socket.descriptor.out + ")")
end end
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".before process_incoming_connection {" + l_accepted_socket.descriptor.out + "}" ) dbglog (generator + ".before process_waiting_incoming_connection")
end end
l_connection_handler.process_incoming_connection (l_accepted_socket) l_connection_handler.accept_incoming_connection (l_listening_socket)
debug ("dbglog") debug ("dbglog")
dbglog (generator + ".after process_incoming_connection {" + l_accepted_socket.descriptor.out + "}") dbglog (generator + ".after process_waiting_incoming_connection")
end
end
end end
update_is_shutdown_requested (l_connection_handler) update_is_shutdown_requested (l_connection_handler)
end end
wait_for_connection_handler_completion (l_connection_handler) wait_for_connection_handler_completion (l_connection_handler)
@@ -304,7 +298,7 @@ feature -- Output
end end
note note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -12,7 +12,8 @@ class
create create
make_server_by_address_and_port, make_server_by_address_and_port,
make_server_by_port, make_server_by_port,
make_from_separate make_from_separate,
make_empty
create {HTTPD_STREAM_SOCKET} create {HTTPD_STREAM_SOCKET}
make make
@@ -36,6 +37,11 @@ feature {NONE} -- Initialization
create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket) create {TCP_STREAM_SOCKET} socket.make_from_separate (s.socket)
end end
make_empty
do
create {TCP_STREAM_SOCKET} socket.make_empty
end
retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER retrieve_socket (s: HTTPD_STREAM_SOCKET): INTEGER
do do
Result := s.socket.descriptor Result := s.socket.descriptor
@@ -147,6 +153,13 @@ feature -- Status Report
end end
end end
is_created: BOOLEAN
do
if attached {NETWORK_SOCKET} socket as l_socket then
Result := l_socket.is_created
end
end
socket_ok: BOOLEAN socket_ok: BOOLEAN
do do
Result := socket.socket_ok Result := socket.socket_ok
@@ -194,6 +207,18 @@ feature -- Status Report
socket.accept socket.accept
end end
accept_to (other: separate HTTPD_STREAM_SOCKET)
-- Accept a new connection on listen socket.
-- Socket of accepted connection is available in `other'.
do
if
attached {NETWORK_STREAM_SOCKET} socket as l_socket and then
attached {separate NETWORK_STREAM_SOCKET} other.socket as l_other_socket
then
l_socket.accept_to (l_other_socket)
end
end
set_blocking set_blocking
do do
socket.set_blocking socket.set_blocking
@@ -225,7 +250,7 @@ feature -- Status Report
accepted: detachable HTTPD_STREAM_SOCKET accepted: detachable HTTPD_STREAM_SOCKET
do do
if attached socket.accepted as l_accepted then if attached {NETWORK_STREAM_SOCKET} socket.accepted as l_accepted then
create Result.make (l_accepted) create Result.make (l_accepted)
end end
end end
@@ -239,8 +264,15 @@ feature {HTTPD_STREAM_SOCKET} -- Implementation
socket: STREAM_SOCKET socket: STREAM_SOCKET
network_stream_socket: detachable NETWORK_STREAM_SOCKET
do
if attached {NETWORK_STREAM_SOCKET} socket as s then
Result := s
end
end
;note ;note
copyright: "2011-2014, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[ source: "[
Eiffel Software Eiffel Software

View File

@@ -15,11 +15,11 @@ inherit
create create
make_server_by_address_and_port, make_server_by_address_and_port,
make_server_by_port, make_server_by_port,
make_from_separate make_from_separate,
make_empty
create {NETWORK_STREAM_SOCKET} create {NETWORK_STREAM_SOCKET}
make_from_descriptor_and_address, make_from_descriptor_and_address
make_empty
feature {NONE} -- Initialization feature {NONE} -- Initialization
@@ -27,8 +27,10 @@ feature {NONE} -- Initialization
-- Create a network stream socket. -- Create a network stream socket.
do do
Precursor Precursor
debug
set_reuse_address set_reuse_address
end end
end
make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER) make_server_by_address_and_port (an_address: INET_ADDRESS; a_port: INTEGER)
-- Create server socket on `an_address' and `a_port'. -- Create server socket on `an_address' and `a_port'.