Moved httpd library from ewsgi/connectors/standalone/lib/httpd to httpd.

Reused the http_network library as well inside httpd library.
This commit is contained in:
2016-10-12 22:54:21 +02:00
parent d28f794828
commit c132d7734b
48 changed files with 86 additions and 73 deletions

View File

@@ -0,0 +1,146 @@
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

View File

@@ -0,0 +1,62 @@
note
description: "[
Instance of HTTPD_REQUEST_HANDLER will process the incoming connection
and extract information on the request and the server
]"
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_REQUEST_HANDLER
inherit
HTTPD_REQUEST_HANDLER_I
redefine
release
end
CONCURRENT_POOL_ITEM
rename
release as release_pool_item
end
feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release
-- <Precursor>
local
d: detachable STRING
do
debug ("dbglog")
if
attached internal_client_socket as l_socket and then
l_socket.descriptor_available
then
d := l_socket.descriptor.out
else
d := "N/A"
end
dbglog (generator + ".release: ENTER {" + d + "}")
end
Precursor {HTTPD_REQUEST_HANDLER_I}
release_pool_item
debug ("dbglog")
if d /= Void then
dbglog (generator + ".release: LEAVE {" + d + "}")
else
dbglog (generator + ".release: LEAVE {N/A}")
end
end
end
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

View File

@@ -0,0 +1,27 @@
note
description: "Implementation of request handler factory for concurrency mode: SCOOP"
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_REQUEST_HANDLER_FACTORY
inherit
HTTPD_REQUEST_HANDLER_FACTORY_I
CONCURRENT_POOL_FACTORY [HTTPD_REQUEST_HANDLER]
rename
new_separate_item as new_handler
end
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

View File

@@ -0,0 +1,190 @@
note
description: "Concurrent pool for SCOOP concurrency mode."
date: "$Date$"
revision: "$Revision$"
class
CONCURRENT_POOL [G -> CONCURRENT_POOL_ITEM]
inherit
HTTPD_DEBUG_FACILITIES
create
make
feature {NONE} -- Initialization
make (n: INTEGER)
do
capacity := n
create items.make_empty (n)
create busy_items.make_empty (n)
end
feature -- Access
count: INTEGER
-- Number of concurrent items managed by Current pool.
capacity: INTEGER
-- Maximum number of concurrent items managed by Current pool.
feature -- Status report
is_full: BOOLEAN
-- Pool is full?
do
Result := count >= capacity
end
is_empty: BOOLEAN
-- No concurrent item waiting in current pool.
do
Result := count = 0
end
stop_requested: BOOLEAN
-- Current pool received a request to terminate.
feature -- Access
separate_item (a_factory: separate CONCURRENT_POOL_FACTORY [G]): detachable separate G
-- Reused, or new separate item of type {G} created by `a_factory'.
require
is_not_full: not is_full
local
i,n,pos: INTEGER
lst: like busy_items
l_item: detachable separate G
do
if not stop_requested then
from
lst := busy_items
pos := -1
i := 0
n := lst.count - 1
until
i > n or l_item /= Void or pos >= 0
loop
if not lst [i] then -- is free (i.e not busy)
pos := i
if items.valid_index (pos) then
l_item := items [pos]
if l_item /= Void then
busy_items [pos] := True
end
end
if l_item = Void then
-- Empty, then let's create one.
l_item := a_factory.new_separate_item
register_item (l_item)
items [pos] := l_item
end
end
i := i + 1
end
if l_item = Void then
-- Pool is FULL ...
check overcapacity: False end
else
debug ("pool", "dbglog")
dbglog ("Lock pool item #" + pos.out + " (free:"+ (capacity - count).out +"))")
end
count := count + 1
busy_items [pos] := True
Result := l_item
a_factory.update_item (l_item)
end
end
end
feature -- Basic operation
gracefull_stop
-- Request the Current pool to terminate.
do
stop_requested := True
end
feature {NONE} -- Internal
items: SPECIAL [detachable separate G]
-- List of concurrent items.
busy_items: SPECIAL [BOOLEAN]
-- Map of items being proceed.
feature {CONCURRENT_POOL_ITEM} -- Change
release_item (a_item: separate G)
-- Unregister `a_item' from Current pool.
require
count > 0
local
i,n,pos: INTEGER
lst: like items
do
-- release handler for reuse
from
lst := items
i := 0
n := lst.count - 1
until
i > n or lst [i] = a_item
loop
i := i + 1
end
if i <= n then
pos := i
busy_items [pos] := False
count := count - 1
--reuse items [pos] := Void
debug ("pool", "dbglog")
dbglog ("Released pool item #" + i.out + " (free:"+ (capacity - count).out +"))")
end
else
check known_item: False end
end
end
feature -- Change
set_count (n: INTEGER)
-- Set capacity of Current pool to `n'.
local
g: detachable separate G
do
capacity := n
items.fill_with (g, 0, n - 1)
busy_items.fill_with (False, 0, n - 1)
end
terminate
-- Terminate current pool.
local
l_items: like items
do
l_items := items
l_items.wipe_out
end
feature {NONE} -- Implementation
register_item (a_item: separate G)
-- Adopt `a_item' in current pool.
do
a_item.set_pool (Current)
end
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

View File

@@ -0,0 +1,31 @@
note
description: "Factory in charge of creating new concurrent pool item."
date: "$Date$"
revision: "$Revision$"
deferred class
CONCURRENT_POOL_FACTORY [G -> CONCURRENT_POOL_ITEM]
feature -- Access
update_item (a_item: separate G)
-- Update `a_item' for optionally purpose.
do
end
new_separate_item: separate G
-- New separated object of type {G}.
deferred
end
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

View File

@@ -0,0 +1,52 @@
note
description: "[
Item create by the CONCURRENT_POOL_FACTORY, and managed by the CONCURRENT_POOL
for SCOOP concurrency mode.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CONCURRENT_POOL_ITEM
feature {NONE} -- Access
pool: detachable separate CONCURRENT_POOL [CONCURRENT_POOL_ITEM]
-- Associated concurrent pool component.
feature {CONCURRENT_POOL} -- Change
set_pool (p: like pool)
-- Set associated `pool' to `p'.
do
pool := p
end
feature {CONCURRENT_POOL, HTTPD_CONNECTION_HANDLER_I} -- Basic operation
release
-- Release Current pool item from associated pool.
do
if attached pool as p then
pool_release (p)
end
end
feature {NONE} -- Implementation
pool_release (p: separate CONCURRENT_POOL [CONCURRENT_POOL_ITEM])
do
p.release_item (Current)
end
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