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,103 @@
note
description: "[
Implementation of HTTPD_CONNECTION_HANDLER_I for concurrency mode: Thread
]"
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
do
n := max_concurrent_connections (server).max (1) -- At least one thread!
create pool.make (n.to_natural_32)
end
feature -- Access
is_shutdown_requested: BOOLEAN
max_concurrent_connections (a_server: like server): INTEGER
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)
do
p.terminate
end
accept_incoming_connection (a_listening_socket: HTTPD_STREAM_SOCKET)
local
cl: separate HTTPD_STREAM_SOCKET
do
debug ("dbglog")
dbglog (generator + ".ENTER accept_connection {"+ a_listening_socket.descriptor.out +"}")
end
if is_shutdown_requested then
-- cancel
elseif attached factory.new_handler as h then
cl := h.client_socket
a_listening_socket.accept_to (cl)
if h.is_connected then
pool.add_work (agent h.safe_execute)
end
end
debug ("dbglog")
dbglog (generator + ".LEAVE accept_incoming_connection {"+ a_listening_socket.descriptor.out +"}")
end
end
feature {HTTPD_SERVER_I} -- Status report
wait_for_completion
-- Wait until Current is ready for shutdown
do
pool.wait_for_completion
end
feature {NONE} -- Access
pool: THREAD_POOL [HTTPD_REQUEST_HANDLER] --ANY] --POOLED_THREAD [HTTP_REQUEST_HANDLER]]
-- Pool of concurrent 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,56 @@
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
feature {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}
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,15 @@
note
description: "Implementation of request handler factory for concurrency mode: Thread"
date: "$Date$"
revision: "$Revision$"
deferred class
HTTPD_REQUEST_HANDLER_FACTORY
inherit
HTTPD_REQUEST_HANDLER_FACTORY_I
note
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -0,0 +1,121 @@
note
description: "{POOLED_THREAD} is used in combination with {THREAD_POOL} to allow for pooled threads."
legal: "See notice at end of class."
status: "Community Preview 1.0"
date: "$Date: 2009-09-01 19:15:37 -0300 (mar 01 de sep de 2009) $"
revision: "$Revision: 80577 $"
class
POOLED_THREAD [G]
inherit
THREAD
rename
make as thread_make
end
create {THREAD_POOL}
make
feature {NONE} -- Initialization
make (a_thread_pool: THREAD_POOL [G]; a_semaphore: SEMAPHORE)
-- `a_thread_pool', the pool in which this thread is managed
-- `a_semaphore' is used for execution suspending
do
thread_make
thread_pool := a_thread_pool
semaphore := a_semaphore
end
feature {NONE} -- Access
thread_pool: THREAD_POOL [G]
-- Pool manager in which this thread is pooled
target: detachable G
-- Target on which the `thread_procedure' should be applied
-- Depending on which launch is used, target is not used
thread_procedure: detachable PROCEDURE
-- Work that should be executed by the thread
semaphore: SEMAPHORE
-- Semaphore share with all threads in a thread pool
-- to suspend execution until more work is available
feature -- Access
set_target (a_target: G)
-- Sets the target on which the work should be executed
do
target := a_target
end
feature {NONE} -- Implementation
execute
-- <Precursor>
local
done: BOOLEAN
do
from
semaphore.wait
thread_procedure := thread_pool.get_work (Current)
until
done
loop
if attached thread_procedure as l_work then
if attached target as t then
l_work.call ([t])
else
l_work.call (Void)
end
end
if thread_pool.over then
done := True
else
thread_procedure := thread_pool.get_work (Current)
if thread_procedure = Void then
semaphore.wait
thread_procedure := thread_pool.get_work (Current)
end
end
end
thread_pool.thread_terminated (Current)
end
note
copyright: "2011-2012, Javier Velilla and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
licensing_options: "http://www.eiffel.com/licensing"
copying: "[
This file is part of Eiffel Software's Eiffel Development Environment.
Eiffel Software's Eiffel Development Environment is free
software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published
by the Free Software Foundation, version 2 of the License
(available at the URL listed under "license" above).
Eiffel Software's Eiffel Development Environment is
distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with Eiffel Software's Eiffel Development
Environment; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
]"
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,228 @@
note
description: "[
A thread pool manager. Manages threads up to `capacity' and queue after that,
till threads get available again.
]"
legal: "See notice at end of class."
status: "Community Preview 1.0"
date: "$Date: 2009-09-01 19:15:37 -0300 (mar 01 de sep de 2009) $"
revision: "$Revision: 80577 $"
class
THREAD_POOL [G]
inherit
EXECUTION_ENVIRONMENT
create
make
feature {NONE} -- Initialization
make (n: like capacity)
-- Initialize current pool with capacity `n'.
require
n_positive: n > 0
n_not_too_large: n < {INTEGER_32}.max_value.as_natural_32
local
i: NATURAL
do
capacity := n
create work_queue.make (n.to_integer_32)
create work_queue_mutex.make
create over_mutex.make
create termination_mutex.make
create work_semaphore.make (capacity.as_integer_32)
from
i := 1
until
i > capacity
loop
work_semaphore.wait
i := i + 1
end
initialize_threads
terminated_count := capacity
is_over := False
ensure
capacity_set: capacity = n
work_queue_set: work_queue.is_empty
end
initialize_threads
-- Launches all threads
local
i: NATURAL
thread: POOLED_THREAD [G]
do
from
i := 1
until
i > capacity
loop
create thread.make (Current, work_semaphore)
thread.launch
i := i + 1
end
end
feature -- Access
capacity: NATURAL
-- Maximal number of threads allowed (queuing otherwise)
queue_count: NATURAL
-- Number of items in queue
do
work_queue_mutex.lock
Result := work_queue.count.as_natural_32
work_queue_mutex.unlock
end
feature -- Status report
valid_action (a_action: PROCEDURE): BOOLEAN
-- Is `a_action' a valid action for the current pool.
do
-- There should be no open operands.
Result := a_action.valid_operands (Void)
end
feature -- Basic operations
add_work (work: PROCEDURE)
-- Launches a thread with the specified argument `arg'. Reuse of thread if possible.
require
valid_action: valid_action (work)
do
work_queue_mutex.lock
work_queue.extend (work)
if work_queue.count <= capacity.as_integer_32 then
-- Let one thread wake up and do the work
work_semaphore.post
end
work_queue_mutex.unlock
end
over: BOOLEAN
-- Is the thread pool being terminated?
do
over_mutex.lock
Result := is_over
over_mutex.unlock
end
thread_terminated (a_thread: POOLED_THREAD [G])
-- Notifies the thread pool that a thread has terminated its execution.
do
termination_mutex.lock
terminated_count := terminated_count - 1
termination_mutex.unlock
end
get_work (requester: POOLED_THREAD [G]): detachable PROCEDURE
-- If there is work to do, it is returned
-- Yields Void otherwise
do
if not over then
work_queue_mutex.lock
if not work_queue.is_empty then
Result := work_queue.item
work_queue.remove
end
work_queue_mutex.unlock
end
end
wait_for_completion
-- Wait until there is no more work to be completed
local
done: BOOLEAN
do
from
until
done
loop
work_queue_mutex.lock
done := work_queue.is_empty
work_queue_mutex.unlock
if not done then
sleep (1)
end
end
end
terminate
-- Terminates all the threads after their execution
do
over_mutex.lock
is_over := True
over_mutex.unlock
from
termination_mutex.lock
until
terminated_count = 0
loop
work_semaphore.post
termination_mutex.unlock
termination_mutex.lock
end
termination_mutex.unlock
end
feature {NONE} -- Implementation: Access
work_queue: ARRAYED_QUEUE [PROCEDURE]
-- Queue that holds unprocessed requests as agents
-- Thread-safe access when accessor holds `queue_mutex'
work_queue_mutex: MUTEX
-- Mutex for the queue
work_semaphore: SEMAPHORE
-- Semaphore which hols the number of work to be done.
-- Needed to wake up worker threads
terminated_count: NATURAL
--
is_over: BOOLEAN
-- Is the thread pool being terminated?
over_mutex: MUTEX
-- Mutex for the `is_over' variable
termination_mutex: MUTEX
;note
copyright: "2011-2012, Javier Velilla, Jocelyn Fiat and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
licensing_options: "http://www.eiffel.com/licensing"
copying: "[
This file is part of Eiffel Software's Eiffel Development Environment.
Eiffel Software's Eiffel Development Environment is free
software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published
by the Free Software Foundation, version 2 of the License
(available at the URL listed under "license" above).
Eiffel Software's Eiffel Development Environment is
distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with Eiffel Software's Eiffel Development
Environment; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
]"
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