1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- S Y S T E M . R P C --
10 -- Copyright (C) 1992-2001 Free Software Foundation, Inc. --
12 -- GNAT is free software; you can redistribute it and/or modify it under --
13 -- terms of the GNU General Public License as published by the Free Soft- --
14 -- ware Foundation; either version 2, or (at your option) any later ver- --
15 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
16 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
17 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
18 -- for more details. You should have received a copy of the GNU General --
19 -- Public License distributed with GNAT; see file COPYING. If not, write --
20 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
21 -- MA 02111-1307, USA. --
23 -- As a special exception, if other files instantiate generics from this --
24 -- unit, or you link this unit with other files to produce an executable, --
25 -- this unit does not by itself cause the resulting executable to be --
26 -- covered by the GNU General Public License. This exception does not --
27 -- however invalidate any other reasons why the executable file might be --
28 -- covered by the GNU Public License. --
30 -- GNAT was originally developed by the GNAT team at New York University. --
31 -- Extensive contributions were provided by Ada Core Technologies Inc. --
33 ------------------------------------------------------------------------------
37 with Unchecked_Deallocation
;
40 with System
.RPC
.Net_Trace
;
41 with System
.RPC
.Garlic
;
42 with System
.RPC
.Streams
;
43 pragma Elaborate
(System
.RPC
.Garlic
);
45 package body System
.RPC
is
47 -- ??? general note: the debugging calls are very heavy, especially
48 -- those that create exception handlers in every procedure. Do we
49 -- really still need all this stuff?
51 use type Ada
.Streams
.Stream_Element_Count
;
52 use type Ada
.Streams
.Stream_Element_Offset
;
54 use type Garlic
.Protocol_Access
;
55 use type Garlic
.Lock_Method
;
57 Max_Of_Message_Id
: constant := 127;
59 subtype Message_Id_Type
is
60 Integer range -Max_Of_Message_Id
.. Max_Of_Message_Id
;
61 -- A message id is either a request id or reply id. A message id is
62 -- provided with a message to a receiving stub which uses the opposite
63 -- as a reply id. A message id helps to retrieve to which task is
64 -- addressed a reply. When the environment task receives a message, the
65 -- message id is extracted : a positive message id stands for a call, a
66 -- negative message id stands for a reply. A null message id stands for
67 -- an asynchronous request.
69 subtype Request_Id_Type
is Message_Id_Type
range 1 .. Max_Of_Message_Id
;
70 -- When a message id is positive, it is a request
72 type Message_Length_Per_Request
is array (Request_Id_Type
)
73 of Ada
.Streams
.Stream_Element_Count
;
75 Header_Size
: Ada
.Streams
.Stream_Element_Count
:=
76 Streams
.Get_Integer_Initial_Size
+
77 Streams
.Get_SEC_Initial_Size
;
78 -- Initial size needed for frequently used header streams
80 Stream_Error
: exception;
81 -- Occurs when a read procedure is executed on an empty stream
82 -- or when a write procedure is executed on a full stream
84 Partition_RPC_Receiver
: RPC_Receiver
;
85 -- Cache the RPC_Recevier passed by Establish_RPC_Receiver
87 type Anonymous_Task_Node
;
89 type Anonymous_Task_Node_Access
is access Anonymous_Task_Node
;
90 -- Types we need to construct a singly linked list of anonymous tasks
91 -- This pool is maintained to avoid a task creation each time a RPC
92 -- occurs - to be cont'd
94 task type Anonymous_Task_Type
(Self
: Anonymous_Task_Node_Access
) is
97 (Message_Id
: in Message_Id_Type
;
98 Partition
: in Partition_ID
;
99 Params_Size
: in Ada
.Streams
.Stream_Element_Count
;
100 Result_Size
: in Ada
.Streams
.Stream_Element_Count
;
101 Protocol
: in Garlic
.Protocol_Access
);
102 -- This entry provides an anonymous task a remote call to perform.
103 -- This task calls for a Request id is provided to construct the
104 -- reply id by using -Request. Partition is used to send the reply
105 -- message. Params_Size is the size of the calling stub Params stream.
106 -- Then Protocol (used by the environment task previously) allows
107 -- extraction of the message following the header (The header is
108 -- extracted by the environment task)
109 -- Note: grammar in above is obscure??? needs cleanup
111 end Anonymous_Task_Type
;
113 type Anonymous_Task_Access
is access Anonymous_Task_Type
;
115 type Anonymous_Task_List
is record
116 Head
: Anonymous_Task_Node_Access
;
117 Tail
: Anonymous_Task_Node_Access
;
120 type Anonymous_Task_Node
is record
121 Element
: Anonymous_Task_Access
;
122 Next
: Anonymous_Task_Node_Access
;
124 -- Types we need to construct a singly linked list of anonymous tasks.
125 -- This pool is maintained to avoid a task creation each time a RPC occurs.
127 protected Garbage_Collector
is
130 (Item
: out Anonymous_Task_Node_Access
);
131 -- Anonymous task pool management : if there is an anonymous task
132 -- left, use it. Otherwise, allocate a new one
135 (Item
: in out Anonymous_Task_Node_Access
);
136 -- Anonymous task pool management : queue this task in the pool
137 -- of inactive anonymous tasks.
141 Anonymous_List
: Anonymous_Task_Node_Access
;
142 -- The list root of inactive anonymous tasks
144 end Garbage_Collector
;
148 entry New_Request
(Request
: out Request_Id_Type
);
149 -- To get a new request
151 entry Wait_On
(Request_Id_Type
)
152 (Length
: out Ada
.Streams
.Stream_Element_Count
);
153 -- To block the calling stub when it waits for a reply
154 -- When it is resumed, we provide the size of the reply
157 (Request
: in Request_Id_Type
;
158 Length
: in Ada
.Streams
.Stream_Element_Count
);
159 -- To wake up the calling stub when the environnement task has
160 -- received a reply for this request
164 task Environnement
is
167 -- Receive no message until Partition_Receiver is set
168 -- Establish_RPC_Receiver decides when the environment task
169 -- is allowed to start
173 protected Partition_Receiver
is
176 -- Blocks if the Partition_RPC_Receiver has not been set
179 -- Done by Establish_RPC_Receiver when Partition_RPC_Receiver
184 Was_Set
: Boolean := False;
185 -- True when Partition_RPC_Receiver has been set
187 end Partition_Receiver
;
188 -- Anonymous tasks have to wait for the Partition_RPC_Receiver
192 (D_Elaborate
, -- About the elaboration of this package
193 D_Communication
, -- About calls to Send and Receive
195 D_Exception
); -- Exception handler
198 package Debugging
is new System
.RPC
.Net_Trace
(Debug_Level
, "RPC : ");
202 (Flag
: in Debug_Level
; Info
: in String) renames Debugging
.Debug
;
205 ------------------------
206 -- Partition_Receiver --
207 ------------------------
209 protected body Partition_Receiver
is
211 -------------------------------
212 -- Partition_Receiver.Is_Set --
213 -------------------------------
215 entry Is_Set
when Was_Set
is
220 ----------------------------
221 -- Partition_Receiver.Set --
222 ----------------------------
229 end Partition_Receiver
;
236 (Index
: out Packet_Node_Access
;
237 Stream
: Params_Stream_Type
)
240 Index
:= Stream
.Extra
.Head
;
244 D
(D_Exception
, "exception in Head_Node");
253 (Index
: out Packet_Node_Access
;
254 Stream
: Params_Stream_Type
)
257 Index
:= Stream
.Extra
.Tail
;
261 D
(D_Exception
, "exception in Tail_Node");
269 function Null_Node
(Index
: in Packet_Node_Access
) return Boolean is
275 D
(D_Exception
, "exception in Null_Node");
279 ----------------------
280 -- Delete_Head_Node --
281 ----------------------
283 procedure Delete_Head_Node
(Stream
: in out Params_Stream_Type
) is
286 new Unchecked_Deallocation
287 (Packet_Node
, Packet_Node_Access
);
289 Next_Node
: Packet_Node_Access
:= Stream
.Extra
.Head
.Next
;
292 -- Delete head node and free memory usage
294 Free
(Stream
.Extra
.Head
);
295 Stream
.Extra
.Head
:= Next_Node
;
297 -- If the extra storage is empty, update tail as well
299 if Stream
.Extra
.Head
= null then
300 Stream
.Extra
.Tail
:= null;
305 D
(D_Exception
, "exception in Delete_Head_Node");
307 end Delete_Head_Node
;
313 procedure Next_Node
(Node
: in out Packet_Node_Access
) is
315 -- Node is set to the next node
316 -- If not possible, Stream_Error is raised
326 D
(D_Exception
, "exception in Next_Node");
330 ---------------------
331 -- Append_New_Node --
332 ---------------------
334 procedure Append_New_Node
(Stream
: in out Params_Stream_Type
) is
335 Index
: Packet_Node_Access
;
338 -- Set Index to the end of the linked list
340 Tail_Node
(Index
, Stream
);
342 if Null_Node
(Index
) then
344 -- The list is empty : set head as well
346 Stream
.Extra
.Head
:= new Packet_Node
;
347 Stream
.Extra
.Tail
:= Stream
.Extra
.Head
;
350 -- The list is not empty : link new node with tail
352 Stream
.Extra
.Tail
.Next
:= new Packet_Node
;
353 Stream
.Extra
.Tail
:= Stream
.Extra
.Tail
.Next
;
359 D
(D_Exception
, "exception in Append_New_Node");
368 (Stream
: in out Params_Stream_Type
;
369 Item
: out Ada
.Streams
.Stream_Element_Array
;
370 Last
: out Ada
.Streams
.Stream_Element_Offset
)
371 renames System
.RPC
.Streams
.Read
;
378 (Stream
: in out Params_Stream_Type
;
379 Item
: in Ada
.Streams
.Stream_Element_Array
)
380 renames System
.RPC
.Streams
.Write
;
382 -----------------------
383 -- Garbage_Collector --
384 -----------------------
386 protected body Garbage_Collector
is
388 --------------------------------
389 -- Garbage_Collector.Allocate --
390 --------------------------------
392 procedure Allocate
(Item
: out Anonymous_Task_Node_Access
) is
393 New_Anonymous_Task_Node
: Anonymous_Task_Node_Access
;
394 Anonymous_Task
: Anonymous_Task_Access
;
397 -- If the list is empty, allocate a new anonymous task
398 -- Otherwise, reuse the first queued anonymous task
400 if Anonymous_List
= null then
402 -- Create a new anonymous task
403 -- Provide this new task with its id to allow it
404 -- to enqueue itself into the free anonymous task list
405 -- with the function Deallocate
407 New_Anonymous_Task_Node
:= new Anonymous_Task_Node
;
409 new Anonymous_Task_Type
(New_Anonymous_Task_Node
);
410 New_Anonymous_Task_Node
.all := (Anonymous_Task
, null);
413 -- Extract one task from the list
414 -- Set the Next field to null to avoid possible bugs
416 New_Anonymous_Task_Node
:= Anonymous_List
;
417 Anonymous_List
:= Anonymous_List
.Next
;
418 New_Anonymous_Task_Node
.Next
:= null;
422 -- Item is an out parameter
424 Item
:= New_Anonymous_Task_Node
;
428 D
(D_Exception
, "exception in Allocate (Anonymous Task)");
432 ----------------------------------
433 -- Garbage_Collector.Deallocate --
434 ----------------------------------
436 procedure Deallocate
(Item
: in out Anonymous_Task_Node_Access
) is
438 -- Enqueue the task in the free list
440 Item
.Next
:= Anonymous_List
;
441 Anonymous_List
:= Item
;
445 D
(D_Exception
, "exception in Deallocate (Anonymous Task)");
449 end Garbage_Collector
;
456 (Partition
: Partition_ID
;
457 Params
: access Params_Stream_Type
;
458 Result
: access Params_Stream_Type
)
460 Protocol
: Protocol_Access
;
461 Request
: Request_Id_Type
;
462 Header
: aliased Params_Stream_Type
(Header_Size
);
463 R_Length
: Ada
.Streams
.Stream_Element_Count
;
466 -- Parameters order :
467 -- Opcode (provided and used by garlic)
468 -- (1) Size (provided by s-rpc and used by garlic)
469 -- (size of (2)+(3)+(4)+(5))
470 -- (2) Request (provided by calling stub (resp receiving stub) and
471 -- used by anonymous task (resp Do_RPC))
472 -- *** ZERO IF APC ***
473 -- (3) Res.len. (provided by calling stubs and used by anonymous task)
474 -- *** ZERO IF APC ***
475 -- (4) Receiver (provided by calling stubs and used by anonymous task)
476 -- (5) Params (provided by calling stubs and used by anonymous task)
478 -- The call is a remote call or a local call. A local call occurs
479 -- when the pragma All_Calls_Remote has been specified. Do_RPC is
480 -- called and the execution has to be performed in the PCS
482 if Partition
/= Garlic
.Get_My_Partition_ID
then
484 -- Get a request id to be resumed when the reply arrives
486 Dispatcher
.New_Request
(Request
);
488 -- Build header = request (2) + result.initial_size (3)
490 D
(D_Debug
, "Do_RPC - Build header");
491 Streams
.Allocate
(Header
);
492 Streams
.Integer_Write_Attribute
-- (2)
493 (Header
'Access, Request
);
494 System
.RPC
.Streams
.SEC_Write_Attribute
-- (3)
495 (Header
'Access, Result
.Initial_Size
);
497 -- Get a protocol method to communicate with the remote partition
498 -- and give the message size
501 "Do_RPC - Lookup for protocol to talk to partition" &
502 Partition_ID
'Image (Partition
));
505 Streams
.Get_Stream_Size
(Header
'Access) +
506 Streams
.Get_Stream_Size
(Params
), -- (1)
510 -- Send the header by using the protocol method
512 D
(D_Communication
, "Do_RPC - Send Header to partition" &
513 Partition_ID
'Image (Partition
));
517 Header
'Access); -- (2) + (3)
519 -- The header is deallocated
521 Streams
.Deallocate
(Header
);
523 -- Send Params from Do_RPC
525 D
(D_Communication
, "Do_RPC - Send Params to partition" &
526 Partition_ID
'Image (Partition
));
530 Params
); -- (4) + (5)
532 -- Let Garlic know we have nothing else to send
537 D
(D_Debug
, "Do_RPC - Suspend");
539 -- Wait for a reply and get the reply message length
541 Dispatcher
.Wait_On
(Request
) (R_Length
);
542 D
(D_Debug
, "Do_RPC - Resume");
545 New_Result
: aliased Params_Stream_Type
(R_Length
);
547 -- Adjust the Result stream size right now to be able to load
548 -- the stream in one receive call. Create a temporary resutl
549 -- that will be substituted to Do_RPC one
551 Streams
.Allocate
(New_Result
);
553 -- Receive the reply message from receiving stub
555 D
(D_Communication
, "Do_RPC - Receive Result from partition" &
556 Partition_ID
'Image (Partition
));
562 -- Let Garlic know we have nothing else to receive
564 Garlic
.Complete_Receive
568 -- Update calling stub Result stream
570 D
(D_Debug
, "Do_RPC - Reconstruct Result");
571 Streams
.Deallocate
(Result
.all);
572 Result
.Initial
:= New_Result
.Initial
;
573 Streams
.Dump
("|||", Result
.all);
578 -- Do RPC locally and first wait for Partition_RPC_Receiver to be
581 Partition_Receiver
.Is_Set
;
582 D
(D_Debug
, "Do_RPC - Locally");
583 Partition_RPC_Receiver
.all (Params
, Result
);
589 D
(D_Exception
, "exception in Do_RPC");
598 (Partition
: Partition_ID
;
599 Params
: access Params_Stream_Type
)
601 Message_Id
: Message_Id_Type
:= 0;
602 Protocol
: Protocol_Access
;
603 Header
: aliased Params_Stream_Type
(Header_Size
);
606 -- For more informations, see above
607 -- Request = 0 as we are not waiting for a reply message
608 -- Result length = 0 as we don't expect a result at all
610 if Partition
/= Garlic
.Get_My_Partition_ID
then
612 -- Build header = request (2) + result.initial_size (3)
613 -- As we have an APC, the request id is null to indicate
614 -- to the receiving stub that we do not expect a reply
615 -- This comes from 0 = -0
617 D
(D_Debug
, "Do_APC - Build Header");
618 Streams
.Allocate
(Header
);
619 Streams
.Integer_Write_Attribute
620 (Header
'Access, Integer (Message_Id
));
621 Streams
.SEC_Write_Attribute
624 -- Get a protocol method to communicate with the remote partition
625 -- and give the message size
628 "Do_APC - Lookup for protocol to talk to partition" &
629 Partition_ID
'Image (Partition
));
632 Streams
.Get_Stream_Size
(Header
'Access) +
633 Streams
.Get_Stream_Size
(Params
),
637 -- Send the header by using the protocol method
639 D
(D_Communication
, "Do_APC - Send Header to partition" &
640 Partition_ID
'Image (Partition
));
646 -- The header is deallocated
648 Streams
.Deallocate
(Header
);
650 -- Send Params from Do_APC
652 D
(D_Communication
, "Do_APC - Send Params to partition" &
653 Partition_ID
'Image (Partition
));
659 -- Let Garlic know we have nothing else to send
667 Result
: aliased Params_Stream_Type
(0);
669 -- Result is here a dummy parameter
670 -- No reason to deallocate as it is not allocated at all
672 Partition_Receiver
.Is_Set
;
673 D
(D_Debug
, "Do_APC - Locally");
674 Partition_RPC_Receiver
.all (Params
, Result
'Access);
682 D
(D_Exception
, "exception in Do_APC");
686 ----------------------------
687 -- Establish_RPC_Receiver --
688 ----------------------------
690 procedure Establish_RPC_Receiver
691 (Partition
: in Partition_ID
;
692 Receiver
: in RPC_Receiver
)
695 -- Set Partition_RPC_Receiver and allow RPC mechanism
697 Partition_RPC_Receiver
:= Receiver
;
698 Partition_Receiver
.Set
;
699 D
(D_Elaborate
, "Partition_Receiver is set");
703 D
(D_Exception
, "exception in Establish_RPC_Receiver");
705 end Establish_RPC_Receiver
;
711 task body Dispatcher
is
712 Last_Request
: Request_Id_Type
:= Request_Id_Type
'First;
713 Current_Rqst
: Request_Id_Type
:= Request_Id_Type
'First;
714 Current_Size
: Ada
.Streams
.Stream_Element_Count
;
720 -- New_Request to get an entry in Dispatcher table
722 -- Wait_On for Do_RPC calls
724 -- Wake_Up called by environment task when a Do_RPC receives
725 -- the result of its remote call
728 accept New_Request
(Request
: out Request_Id_Type
) do
729 Request
:= Last_Request
;
732 -- ??? Avaibility check
734 if Last_Request
= Request_Id_Type
'Last then
735 Last_Request
:= Request_Id_Type
'First;
737 Last_Request
:= Last_Request
+ 1;
744 (Request
: Request_Id_Type
;
745 Length
: Ada
.Streams
.Stream_Element_Count
)
747 -- The environment reads the header and has been notified
748 -- of the reply id and the size of the result message
750 Current_Rqst
:= Request
;
751 Current_Size
:= Length
;
756 -- ??? Must be select with delay for aborted tasks
760 accept Wait_On
(Current_Rqst
)
761 (Length
: out Ada
.Streams
.Stream_Element_Count
)
763 Length
:= Current_Size
;
767 -- To free the Dispatcher when a task is aborted
781 D
(D_Exception
, "exception in Dispatcher body");
785 -------------------------
786 -- Anonymous_Task_Type --
787 -------------------------
789 task body Anonymous_Task_Type
is
790 Whoami
: Anonymous_Task_Node_Access
:= Self
;
791 C_Message_Id
: Message_Id_Type
; -- Current Message Id
792 C_Partition
: Partition_ID
; -- Current Partition
793 Params_S
: Ada
.Streams
.Stream_Element_Count
; -- Params message size
794 Result_S
: Ada
.Streams
.Stream_Element_Count
; -- Result message size
795 C_Protocol
: Protocol_Access
; -- Current Protocol
799 -- Get a new RPC to execute
803 (Message_Id
: in Message_Id_Type
;
804 Partition
: in Partition_ID
;
805 Params_Size
: in Ada
.Streams
.Stream_Element_Count
;
806 Result_Size
: in Ada
.Streams
.Stream_Element_Count
;
807 Protocol
: in Protocol_Access
)
809 C_Message_Id
:= Message_Id
;
810 C_Partition
:= Partition
;
811 Params_S
:= Params_Size
;
812 Result_S
:= Result_Size
;
813 C_Protocol
:= Protocol
;
820 Params
: aliased Params_Stream_Type
(Params_S
);
821 Result
: aliased Params_Stream_Type
(Result_S
);
822 Header
: aliased Params_Stream_Type
(Header_Size
);
825 -- We reconstruct all the client context : Params and Result
826 -- with the SAME size, then we receive Params from calling stub
829 "Anonymous Task - Receive Params from partition" &
830 Partition_ID
'Image (C_Partition
));
836 -- Let Garlic know we don't receive anymore
838 Garlic
.Complete_Receive
842 -- Check that Partition_RPC_Receiver has been set
844 Partition_Receiver
.Is_Set
;
849 "Anonymous Task - Perform Partition_RPC_Receiver for request" &
850 Message_Id_Type
'Image (C_Message_Id
));
851 Partition_RPC_Receiver
(Params
'Access, Result
'Access);
853 -- If this was a RPC we send the result back
854 -- Otherwise, do nothing else than deallocation
856 if C_Message_Id
/= 0 then
858 -- Build Header = -C_Message_Id + Result Size
859 -- Provide the request id to the env task of the calling
860 -- stub partition We get the real result stream size : the
861 -- calling stub (in Do_RPC) updates its size to this one
863 D
(D_Debug
, "Anonymous Task - Build Header");
864 Streams
.Allocate
(Header
);
865 Streams
.Integer_Write_Attribute
866 (Header
'Access, Integer (-C_Message_Id
));
867 Streams
.SEC_Write_Attribute
869 Streams
.Get_Stream_Size
(Result
'Access));
871 -- Get a protocol method to comunicate with the remote
872 -- partition and give the message size
875 "Anonymous Task - Lookup for protocol talk to partition" &
876 Partition_ID
'Image (C_Partition
));
879 Streams
.Get_Stream_Size
(Header
'Access) +
880 Streams
.Get_Stream_Size
(Result
'Access),
884 -- Send the header by using the protocol method
887 "Anonymous Task - Send Header to partition" &
888 Partition_ID
'Image (C_Partition
));
894 -- Send Result toDo_RPC
897 "Anonymous Task - Send Result to partition" &
898 Partition_ID
'Image (C_Partition
));
904 -- Let Garlic know we don't send anymore
909 Streams
.Deallocate
(Header
);
912 Streams
.Deallocate
(Params
);
913 Streams
.Deallocate
(Result
);
916 -- Enqueue into the anonymous task free list : become inactive
918 Garbage_Collector
.Deallocate
(Whoami
);
924 D
(D_Exception
, "exception in Anonymous_Task_Type body");
926 end Anonymous_Task_Type
;
932 task body Environnement
is
933 Partition
: Partition_ID
;
934 Message_Size
: Ada
.Streams
.Stream_Element_Count
;
935 Result_Size
: Ada
.Streams
.Stream_Element_Count
;
936 Message_Id
: Message_Id_Type
;
937 Header
: aliased Params_Stream_Type
(Header_Size
);
938 Protocol
: Protocol_Access
;
939 Anonymous
: Anonymous_Task_Node_Access
;
942 -- Wait the Partition_RPC_Receiver to be set
945 D
(D_Elaborate
, "Environment task elaborated");
948 -- We receive first a fixed size message : the header
949 -- Header = Message Id + Message Size
951 Streams
.Allocate
(Header
);
953 -- Garlic provides the size of the received message and the
954 -- protocol to use to communicate with the calling partition
956 Garlic
.Initiate_Receive
962 "Environment task - Receive protocol to talk to active partition" &
963 Partition_ID
'Image (Partition
));
965 -- Extract the header to route the message either to
966 -- an anonymous task (Message Id > 0 <=> Request Id)
967 -- or to a waiting task (Message Id < 0 <=> Reply Id)
970 "Environment task - Receive Header from partition" &
971 Partition_ID
'Image (Partition
));
977 -- Evaluate the remaining size of the message
979 Message_Size
:= Message_Size
-
980 Streams
.Get_Stream_Size
(Header
'Access);
982 -- Extract from header : message id and message size
984 Streams
.Integer_Read_Attribute
(Header
'Access, Message_Id
);
985 Streams
.SEC_Read_Attribute
(Header
'Access, Result_Size
);
987 if Streams
.Get_Stream_Size
(Header
'Access) /= 0 then
989 -- If there are stream elements left in the header ???
991 D
(D_Exception
, "Header is not empty");
996 if Message_Id
< 0 then
998 -- The message was sent by a receiving stub : wake up the
999 -- calling task - We have a reply there
1001 D
(D_Debug
, "Environment Task - Receive Reply from partition" &
1002 Partition_ID
'Image (Partition
));
1003 Dispatcher
.Wake_Up
(-Message_Id
, Result_Size
);
1006 -- The message was send by a calling stub : get an anonymous
1007 -- task to perform the job
1009 D
(D_Debug
, "Environment Task - Receive Request from partition" &
1010 Partition_ID
'Image (Partition
));
1011 Garbage_Collector
.Allocate
(Anonymous
);
1013 -- We subtracted the size of the header from the size of the
1014 -- global message in order to provide immediatly Params size
1016 Anonymous
.Element
.Start
1025 -- Deallocate header : unnecessary - WARNING
1027 Streams
.Deallocate
(Header
);
1033 D
(D_Exception
, "exception in Environment");
1038 -- Set debugging information
1040 Debugging
.Set_Environment_Variable
("RPC");
1041 Debugging
.Set_Debugging_Name
("D", D_Debug
);
1042 Debugging
.Set_Debugging_Name
("E", D_Exception
);
1043 Debugging
.Set_Debugging_Name
("C", D_Communication
);
1044 Debugging
.Set_Debugging_Name
("Z", D_Elaborate
);
1045 D
(D_Elaborate
, "To be elaborated");
1047 -- When this body is elaborated we should ensure that RCI name server
1048 -- has been already elaborated : this means that Establish_RPC_Receiver
1049 -- has already been called and that Partition_RPC_Receiver is set
1051 Environnement
.Start
;
1052 D
(D_Elaborate
, "ELABORATED");