76 lines
2.3 KiB
Ada
76 lines
2.3 KiB
Ada
|
package body dispatchers is
|
||
|
|
||
|
task body Dispatcher is
|
||
|
HANDLERS_COUNT : constant Integer := 2;
|
||
|
MAX_SOCKETS_COUNT : constant Integer := 1000;
|
||
|
UNDISPATCHED_SOCKET_RETRY_TIME : constant Duration := 0.5;
|
||
|
|
||
|
handlers : array (1 .. HANDLERS_COUNT) of Handler;
|
||
|
|
||
|
type Socket_Index is range 1..MAX_SOCKETS_COUNT;
|
||
|
package Socket_Vector is new Ada.Containers.Vectors (
|
||
|
Element_Type => Socket_Type,
|
||
|
Index_Type => Socket_Index);
|
||
|
|
||
|
function Find_Free_Handler(s: Socket_Type) return Boolean is
|
||
|
begin
|
||
|
for id in handlers'Range loop
|
||
|
select
|
||
|
handlers(id).handle(s);
|
||
|
return True;
|
||
|
else
|
||
|
null;
|
||
|
end select;
|
||
|
end loop;
|
||
|
return False;
|
||
|
end Find_Free_Handler;
|
||
|
|
||
|
result : Boolean;
|
||
|
undispatched : Socket_Vector.Vector;
|
||
|
|
||
|
begin
|
||
|
accept start;
|
||
|
|
||
|
for id in handlers'Range loop
|
||
|
handlers(id).start(id);
|
||
|
end loop;
|
||
|
|
||
|
loop
|
||
|
select
|
||
|
accept dispatch (s: Socket_Type) do
|
||
|
Put_Line ("dispatch command");
|
||
|
result := Find_Free_Handler(s);
|
||
|
if not result then
|
||
|
Put_Line("All handlers are busy");
|
||
|
undispatched.Append(s);
|
||
|
end if;
|
||
|
end dispatch;
|
||
|
or
|
||
|
accept stop do
|
||
|
Put_Line("stop command, stopping dispatcher");
|
||
|
end stop;
|
||
|
exit;
|
||
|
or
|
||
|
delay UNDISPATCHED_SOCKET_RETRY_TIME;
|
||
|
if Integer(undispatched.Length) > 0 then
|
||
|
declare
|
||
|
s: Socket_Type := undispatched.Element(1);
|
||
|
begin
|
||
|
result := Find_Free_Handler(s);
|
||
|
if result then
|
||
|
undispatched.Delete(1);
|
||
|
Put_Line("Handled undispatched client");
|
||
|
end if;
|
||
|
end;
|
||
|
end if;
|
||
|
end select;
|
||
|
end loop;
|
||
|
|
||
|
for id in handlers'Range loop
|
||
|
handlers(id).stop;
|
||
|
end loop;
|
||
|
|
||
|
|
||
|
end dispatcher;
|
||
|
end dispatchers;
|