/****************************************************************************
  module      : vkb90
  author      : JuergenA
  responsible : UweH
  special area: Servertaskhandling
  see also    :
  description : KB_sender_receiver
 
    ========== licence begin  GPL
    Copyright (c) 2001-2004 SAP AG
 
    This program 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; either version 2
    of the License, or (at your option) any later version.
 
    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
 
*****************************************************************************/
 
.tt 1 $SAP$LiveCache$VKB90$
.tt 3 $UweH$KB_sender_receiver$2000-05-22$
 
Module  : KB_sender_receiver
 
Define  :
 
        FUNCTION
              k90all_server_ready (TaskId : tsp00_TaskId) : boolean;
 
        PROCEDURE
              k90allocate_netserver (VAR Trans : tgg00_TransContext);
 
        PROCEDURE
              k90child_reply (
                    VAR mblock           : tgg00_MessBlock;
                    ServerIndex          : tsp00_Int2;
                    VAR ChildTrans       : tgg00_TransChild);
 
        PROCEDURE
              k90clear_netserver (VAR Trans : tgg00_TransContext);
 
        PROCEDURE
              k90dump_netserver (
                    VAR HostFile  : tgg00_VfFileref;
                    VAR buf       : tsp00_Page;
                    VAR OutPno    : tsp00_Int4;
                    VAR OutPos    : integer;
                    VAR HostError : tsp00_VfReturn;
                    VAR ErrorText : tsp00_ErrText);
 
        FUNCTION
              k90free_requests (
                    TaskId             : tsp00_TaskId;
                    mtype              : tgg00_MessType;
                    InRegion           : boolean) : tsp00_Int4;
 
        PROCEDURE
              k90rcv_child (
                    VAR mblock         : tgg00_MessBlock;
                    VAR ChildTrans     : tgg00_TransChild);
 
        PROCEDURE
              k90send (
                    VAR mblock     : tgg00_MessBlock;
                    VAR ChildTrans : tgg00_TransChild);
 
        PROCEDURE
              k90send_prefix_destroy_files (VAR Trans : tgg00_TransContext);
 
        PROCEDURE
              k90server_init (
                    VAR Trans           : tgg00_TransContext;
                    VAR ServerIndex     : tsp00_Int2;
                    VAR IsDynamic       : boolean);
 
        PROCEDURE
              k90sreceive_server (
                    VAR mblock     : tgg00_MessBlock;
                    ServerIndex    : tsp00_Int2;
                    AlreadyIdle    : boolean;
                    VAR ChildTrans : tgg00_TransChild);
 
        PROCEDURE
              k90wait_until_server_finished (TaskId : tsp00_TaskId);
 
        PROCEDURE
              kb90AddToPrefixDestroyFile (
                    VAR trans   : tgg00_TransContext;
                    fileTransId : tgg91_TransNo);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              KB_Check : VKB03;
 
        VAR
              kb03Check : tkb00_Check;
 
      ------------------------------ 
 
        FROM
              KB_transaction: VKB53;
 
        PROCEDURE
              k53server_drop_aux_files (VAR Trans : tgg00_TransContext);
 
      ------------------------------ 
 
        FROM
              KB_server_task : VKB92;
 
        VAR
              k92LogWriterTaskId : tsp00_TaskId;
 
      ------------------------------ 
 
        FROM
              KB_send_rcv_buf_handling : VKB96;
 
        PROCEDURE
              k96clear_mdesc (VAR mdesc : tkb09_MessDesc);
 
        PROCEDURE
              k96errtext_from_mdesc (
                    mdesc           : tkb09_MessDescPtr;
                    VAR ErrTextLen  : tsp00_Int4;
                    VAR ErrTextType : tgg00_ErrorText;
                    VAR ErrText     : tsp00_ErrText;
                    VAR e           : tgg00_BasisError);
 
        PROCEDURE
              k96free_mdesc (
                    VAR MessCache : tkb09_MessCache;
                    VAR mdesc : tkb09_MessDescPtr);
 
        PROCEDURE
              k96free_messbody (
                    VAR MessCache : tkb09_MessCache;
                    VAR MessBody : tkb09_PtrMessBodyDesc);
 
        PROCEDURE
              k96move_from_mdesc (
                    VAR mblock  : tgg00_MessBlock;
                    SourceMdesc : tkb09_MessDescPtr);
 
        PROCEDURE
              k96new_mdesc (
                    VAR Trans         : tgg00_TransContext;
                    VAR MessCache     : tkb09_MessCache;
                    VAR mdesc         : tkb09_MessDescPtr;
                    ParentTaskId      : tsp00_TaskId);
 
        PROCEDURE
              k96to_mdesc_move (
                    VAR MessCache : tkb09_MessCache;
                    VAR mblock  : tgg00_MessBlock;
                    DestinMdesc : tkb09_MessDescPtr);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_1 : VBD01;
 
        VAR
              b01niltree_id : tgg00_FileId;
 
        PROCEDURE
              b01filestate (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
        PROCEDURE
              b01tcreate_file (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              filesysteminterface_2 : VBD02;
 
        PROCEDURE
              b02add_record (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId;
                    VAR b       : tgg00_Rec);
 
        PROCEDURE
              b02del_record (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId;
                    VAR rk      : tgg00_Lkey);
 
        PROCEDURE
              b02next_record (
                    VAR t       : tgg00_TransContext;
                    VAR file_id : tgg00_FileId;
                    VAR rk      : tgg00_Lkey;
                    inclusive   : boolean;
                    VAR b       : tgg00_Rec);
 
      ------------------------------ 
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06put_errtxt (
                    VAR t          : tgg00_TransContext;
                    pid            : tsp00_TaskId;
                    errlen         : integer;
                    etexttype      : tgg00_ErrorText;
                    b_err_in       : tgg00_BasisError;
                    VAR errtxt     : tsp00_ErrText;
                    VAR b_err_out  : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              Trace : VBD120;
 
        PROCEDURE
              b120InsertTrace (
                    VAR t        : tgg00_TransContext;
                    trace_layer  : tgg00_Debug;
                    trace_object : tgg00_VtraceType;
                    body_len     : tsp00_Int2;
                    trace_body   : tsp00_Addr);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01vtrace : tgg00_VtraceState;
 
        PROCEDURE
              g01abort (
                    msg_no     : tsp00_Int4;
                    msg_label  : tsp00_C8;
                    msg_text   : tsp00_C24;
                    bad_value  : tsp00_Int4);
 
        FUNCTION
              g01align (val : tsp00_Int4): tsp00_Int4;
 
        PROCEDURE
              g01allocate_msg (
                    msg_label  : tsp00_C8;
                    msg_text   : tsp00_C24;
                    alloc_size : tsp00_Int4);
 
        FUNCTION
              g01cache_size (cache_type : tgg04_CacheType) : tsp00_Int4;
 
        FUNCTION
              g01calc_usable_desc (
                    mtype          : tgg00_MessType;
                    available_desc : tsp00_Int4) : tsp00_Int4;
 
        PROCEDURE
              g01check (
                    msg_no     : tsp00_Int4;
                    msg_label  : tsp00_C8  (* ptocSynonym char* *);
                    msg_text   : tsp00_C24 (* ptocSynonym char* *);
                    bad_value  : tsp00_Int4;
                    constraint : boolean);
 
        FUNCTION
              g01kbfunction_tasks : tsp00_Int4;
 
        FUNCTION
              g01maxservertask : tsp00_Int4;
 
        FUNCTION
              g01min_server_desc : tsp00_Int4;
 
        PROCEDURE
              g01new_dump_page (
                    VAR hostfile : tgg00_VfFileref;
                    VAR buf      : tsp00_Page;
                    VAR out_pno  : tsp00_Int4;
                    VAR out_pos  : integer;
                    VAR host_err : tsp00_VfReturn;
                    VAR errtext  : tsp00_ErrText);
 
        FUNCTION
              g01packet_size : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              GG_cpp_auxiliary_functions : VGG06;
 
        PROCEDURE
              gg06SetDummyTrans (VAR TransNo : tgg91_TransNo);
 
      ------------------------------ 
 
        FROM
              Regions_and_Longwaits : VGG08;
 
        VAR
              g08server : tsp00_RegionId;
&       ifdef TRACE
 
        PROCEDURE
              g08check_excl (region : tsp00_RegionId);
 
        PROCEDURE
              g08excl_check (
                    pid          : tsp00_TaskId;
                    region       : tsp00_RegionId);
&       endif
 
      ------------------------------ 
 
        FROM
              KernelAdministration_Interface : VGG999;
 
        PROCEDURE
              gg999Offline (error : tgg00_BasisError);
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vallocat (
                    length     : tsp00_Int4;
                    VAR p      : tsp00_ObjAddr;
                    VAR ok     : boolean);
 
        PROCEDURE
              vbegexcl (
                    pid     : tsp00_TaskId;
                    region  : tsp00_RegionId);
 
        PROCEDURE
              vclock (
                    VAR sec      : tsp00_Int4;
                    VAR microsec : tsp00_Int4);
 
        PROCEDURE
              vcreate (
                    proc_type    : tsp2_process_type;
                    VAR pid      : tsp00_TaskId;
                    VAR ok       : boolean);
 
        PROCEDURE
              vendexcl (
                    pid     : tsp00_TaskId;
                    region  : tsp00_RegionId);
 
        PROCEDURE
              vkill (pid : tsp00_TaskId);
 
        PROCEDURE
              vresume (pid : tsp00_TaskId);
 
        PROCEDURE
              vsleep (
                    pid   : tsp00_TaskId;
                    limit : tsp00_Int2);
 
        PROCEDURE
              vsuspend (
                    pid            : tsp00_TaskId;
                    suspend_reason : tsp00_Int2);
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalFill (
                    mod_id   : tsp00_C6;
                    mod_num  : tsp00_Int4;
                    obj_upb  : tsp00_Int4;
                    obj      : tsp00_MoveObjPtr;
                    obj_pos  : tsp00_Int4;
                    length   : tsp00_Int4;
                    fillchar : char;
                    VAR e    : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;            
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;          
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;       
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;       
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
&       ifdef TRACE
 
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01addr (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Sname;
                    bufaddr  : tkb09_MessDescPtr);
 
        PROCEDURE
              t01addr_1 (
                    debug      : tgg00_Debug;
                    nam        : tsp00_Sname;
                    bufaddr    : tkb09_PtrMessBodyDesc);
 
        PROCEDURE
              t01basis_error (
                    debug : tgg00_Debug;
                    nam   : tsp00_Sname;
                    b_err : tgg00_BasisError);
 
        PROCEDURE
              t01int4 (
                    debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    int : tsp00_Int4);
 
        PROCEDURE
              t01p2int4 (
                    debug : tgg00_Debug;
                    nam_1 : tsp00_Sname;
                    int_1 : tsp00_Int4;
                    nam_2 : tsp00_Sname;
                    int_2 : tsp00_Int4);
 
        PROCEDURE
              t01localstate (
                    debug : tgg00_Debug;
                    nam : tsp00_Sname;
                    s   : tgg00_TransState);
 
        PROCEDURE
              t01messblock (
                    debug         : tgg00_Debug;
                    nam           : tsp00_Sname;
                    VAR m         : tgg00_MessBlock);
 
        PROCEDURE
              t01mblock_header (
                    debug             : tgg00_Debug;
                    nam               : tsp00_Sname;
                    VAR mbuf_header   : tgg00_MessBufHeader;
                    VAR trans         : tgg00_TransChild;
                    trans_ptr         : tgg00_TransContextPtr);
 
        PROCEDURE
              t01msgcheck (
                    msg             : tsp00_C30;
                    check_condition : boolean;
                    bad_int         : tsp00_Int4);
 
        PROCEDURE
              t01name (
                    debug    : tgg00_Debug;
                    nam      : tsp00_Name);
 
        PROCEDURE
              t01name1 (
                    debug     : tgg00_Debug;
                    nam       : tsp00_Sname;
                    n         : tsp00_Name);
 
        FUNCTION
              t01trace (debug : tgg00_Debug) : boolean;
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              b06put_errtxt;
 
              tsp00_C256 tsp00_ErrText
 
        PROCEDURE
              b120InsertTrace;
 
              tgg11_VtraceBodyPtr tsp00_Addr
&             ifdef TRACE
 
        PROCEDURE
              t01addr;
 
              tsp00_BufAddr tkb09_MessDescPtr
 
        PROCEDURE
              t01addr_1;
 
              tsp00_BufAddr tkb09_PtrMessBodyDesc
&             endif
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  :
.sp
.cp 3
Created : 1988-11-22
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-05-22
.sp
***********************************************************
.sp
Specification:
 
Update Define:
k90free_requests (* PTS 1000437 UH *)
 
Update Use:
g01calc_usable_desc (* PTS 1000437 UH *)
 
.CM *-END-* specification -------------------------------
.sp 2
************************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
.CM *-END-* description ---------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      (* PTS 1000437 UH *)
      PROC_FILL_GRADE  =  0.7; (* for proc desc hash list *)
      TIMEOUT_SERVER   =  180; (* seconds *)
      TIMEOUT_RECEIVE  =  600; (* seconds *)
      (* *)
      IN_SERVER_REGION = true; (* PTS 1105291 JA 2000-01-07 *)
      INCLUSIVE        = true; (* PTS 1105291 JA 2000-01-07 *)
 
VAR
      kb90_Glob      : tkb09_Glob;
      kb90_MessCache : tkb09_MessCache;
 
 
(*------------------------------*) 
 
FUNCTION
      k90all_server_ready (TaskId : tsp00_TaskId) : boolean;
 
BEGIN
vbegexcl (TaskId, g08server);
IF  kb90_Glob.glServerList_kb09 = NIL
THEN
    k90all_server_ready := false
ELSE
    k90all_server_ready :=
          kb90_Glob.glServerList_kb09^[g01maxservertask].svTaskId_kb09 <> cgg_nil_pid;
(*ENDIF*) 
vendexcl (TaskId, g08server);
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90allocate_netserver (VAR Trans : tgg00_TransContext);
 
VAR
      i        : integer;
      AllocSum : tsp00_Int4;
 
      UnivAddr : RECORD
            CASE integer OF
                1:
                    (uvObjAddr        : tsp00_ObjAddr);
                2:
                    (uvMbodyListAddr  : tkb09_ListMessBodyDesc);
                3:
                    (uvMdescListAddr  : tkb09_ListMessDesc);
                4:
                    (uvMoveObjAddr    : tsp00_MoveObjPtr);
                5:
                    (uvParentListAddr : tkb09_ListParentDesc);
                6:
                    (uvParentHashAddr : tkb09_ListParentHash);
                7:
                    (uvServerListAddr : tkb09_ListServerDesc);
                END;
            (*ENDCASE*) 
 
 
BEGIN
;
k92LogWriterTaskId := cgg_nil_pid;
;
(* PTS 1104043 JA 1999-10-08 *)
(* during xstart serverdb --> vak91 timeout task *)
vbegexcl (Trans.trTaskId_gg00, g08server);
Trans.trError_gg00 := e_ok;
AllocSum           := 0;
WITH kb90_Glob DO
    BEGIN
    (* PTS 1103743 JA 1999-08-25 *)
    glParentList_kb09      := NIL;
    glServerList_kb09      := NIL;
    glFirstServerJob_kb09  := NIL;
    glLastServerJob_kb09   := NIL;
    glParentFirstFree_kb09 := NIL;
    glParentFirstFree_kb09 := NIL;
    (* *)
    glParentMaxItems_kb09  := 0;
    glTimeLastClear_kb09   := 0;
    (* *)
    glServerBusyCnt_kb09   := 0;                      (* PTS 1105291 JA 2000-01-07 *)
    glServerFirstIdle_kb09 := 0;
    glServerStaticCnt_kb09 := 0;
    (* *)
    glServerCallCnt_kb09   := 0;
    (* *)
    glDropFileTask_kb09    := cgg_nil_pid;            (* PTS 1105291 JA 2000-01-07 *)
    glDropFileReqCnt_kb09  := 0;                      (* PTS 1105291 JA 2000-01-07 *)
    glServerReserved_kb09  := g01maxservertask DIV 2; (* PTS 1105291 JA 2000-01-07 *)
    IF  glServerReserved_kb09 > g01min_server_desc
    THEN
        glServerReserved_kb09 := g01min_server_desc;  (* PTS 1105291 JA 2000-01-07 *)
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* *)
(* -----  M E S S  D E S C  L I S T  ----- *)
kb90_MessCache.mcMdescList_kb09     := NIL;
kb90_MessCache.mcMdescMaxItems_kb09 := g01cache_size (cachServerMdesc_egg04);
IF  (kb90_MessCache.mcMdescMaxItems_kb09 > MAX_SERVER_MDESC_GG04)
    OR
    (kb90_MessCache.mcMdescMaxItems_kb09 < 0)
THEN
    Trans.trError_gg00 := e_invalid
ELSE
    kb90vallocate (
          kb90_MessCache.mcMdescMaxItems_kb09 * sizeof (tkb09_MessDesc),
          UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00);
(*ENDIF*) 
IF  Trans.trError_gg00 = e_ok
THEN
    kb90_MessCache.mcMdescList_kb09 := UnivAddr.uvMdescListAddr;
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'KB50 mdesc item size   :',
      sizeof (tkb09_MessDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 mdesc items       :',
      kb90_MessCache.mcMdescMaxItems_kb09);
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 mdesc list size   :',
      kb90_MessCache.mcMdescMaxItems_kb09 * sizeof (tkb09_MessDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 mdesc list aligned:',
      g01align (kb90_MessCache.mcMdescMaxItems_kb09 * sizeof (tkb09_MessDesc)));
(* *)
(* -----  M E S S B O D Y  D E S C  L I S T  ---- *)
kb90_MessCache.mcMbodyList_kb09 := NIL;
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    IF  (g01cache_size (cachServerMbody_egg04) > MAX_SERVER_MDESC_GG04) OR
        (g01cache_size (cachServerMbody_egg04) < 0)
    THEN
        Trans.trError_gg00 := e_invalid
    ELSE
        kb90vallocate (g01cache_size (cachServerMbody_egg04) * sizeof (tkb09_MessBodyDesc),
              UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00);
    (*ENDIF*) 
    END;
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'KB90 packet items      :',
      g01cache_size (cachServerMbody_egg04));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 packet desc size  :',
      sizeof (tkb09_MessBodyDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 packet desc list  :',
      (g01cache_size (cachServerMbody_egg04)) * sizeof (tkb09_MessBodyDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 packet size       :',
      g01packet_size
      - sizeof (tkb09_MessHead)
      - sizeof (tkb09_ShortMessBuf));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 packetsize aligned:',
      g01align (g01packet_size - sizeof (tkb09_MessHead) - sizeof (tkb09_ShortMessBuf)));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 packet list       :',
      g01cache_size (cachServerMbody_egg04)
      * g01align (g01packet_size - sizeof (tkb09_MessHead) - sizeof (tkb09_ShortMessBuf)));
IF  Trans.trError_gg00 = e_ok
THEN
    kb90_MessCache.mcMbodyList_kb09 := UnivAddr.uvMbodyListAddr;
(*ENDIF*) 
i := 1;
WHILE (i <= g01cache_size (cachServerMbody_egg04)) AND (Trans.trError_gg00 = e_ok) DO
    BEGIN
    WITH kb90_MessCache.mcMbodyList_kb09^[i] DO
        BEGIN
        kb90vallocate (g01packet_size
              - sizeof (tkb09_MessHead)
              - sizeof (tkb09_ShortMessBuf),
              UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00);
        IF  Trans.trError_gg00 = e_ok
        THEN
            BEGIN
            mbyBuf_kb09     := UnivAddr.uvMoveObjAddr;
            mbyBufSize_kb09 := g01packet_size - sizeof (tkb09_MessHead)
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    i := i + 1
    END;
(*ENDWHILE*) 
(* -----  P A R E N T  D E S C  L I S T  --------- *)
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    kb90_Glob.glParentMaxItems_kb09 := trunc (g01kbfunction_tasks / PROC_FILL_GRADE);
    IF  kb90_Glob.glParentMaxItems_kb09 > MAX_USER_TASKS_GG04
    THEN
        kb90_Glob.glParentMaxItems_kb09 := MAX_USER_TASKS_GG04
    ELSE
        IF  kb90_Glob.glParentMaxItems_kb09 <= 0
        THEN
            kb90_Glob.glParentMaxItems_kb09 := 1;
        (*ENDIF*) 
    (*ENDIF*) 
    kb90vallocate (kb90_Glob.glParentMaxItems_kb09 * sizeof (tkb09_ParentDesc),
          UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00)
    END;
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'KB90 parent list       :',
      (kb90_Glob.glParentMaxItems_kb09 + 1) * sizeof (tkb09_ParentDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 kbfunction_task   :', g01kbfunction_tasks);
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 parent items / 0.7:', kb90_Glob.glParentMaxItems_kb09);
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 parent desc size  :', sizeof (tkb09_ParentDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 parentdesc aligned:',
      g01align (kb90_Glob.glParentMaxItems_kb09 * sizeof (tkb09_ParentDesc)));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 parent hash list  :',
      kb90_Glob.glParentMaxItems_kb09 * sizeof (tkb09_ParentDescPtr));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 parenthash aligned:',
      g01align (kb90_Glob.glParentMaxItems_kb09 * sizeof (tkb09_ParentDescPtr)));
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    kb90_Glob.glParentList_kb09 := UnivAddr.uvParentListAddr;
    kb90vallocate (kb90_Glob.glParentMaxItems_kb09 * sizeof (tkb09_ParentDescPtr),
          UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00)
    END;
(*ENDIF*) 
IF  Trans.trError_gg00 = e_ok
THEN
    kb90_Glob.glParentHash_kb09 := UnivAddr.uvParentHashAddr;
(*ENDIF*) 
;
(* -----  S E R V E R   D E S C   L I S T  ---- *)
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    IF  (g01maxservertask > MAX_SERVER_TASKS_GG04) OR
        (g01maxservertask < 0)
    THEN
        Trans.trError_gg00 := e_invalid
    ELSE
        kb90vallocate (g01maxservertask * sizeof (tkb09_ServerDesc),
              UnivAddr.uvObjAddr, AllocSum, Trans.trError_gg00);
    (*ENDIF*) 
    END;
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'KB90 maxservertasks    :', g01maxservertask);
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 server desc size  :',
      sizeof (tkb09_ServerDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 server list       :',
      g01maxservertask * sizeof (tkb09_ServerDesc));
(* *)
g01allocate_msg (csp3_n_dynpool, 'KB90 serverlist aligned:',
      g01align (g01maxservertask * sizeof (tkb09_ServerDesc)));
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    kb90_Glob.glServerList_kb09 := UnivAddr.uvServerListAddr;
    FOR i := 1 TO g01maxservertask DO
        WITH kb90_Glob.glServerList_kb09^[i] DO
            BEGIN
            svMdesc_kb09     := NIL;
            svTaskId_kb09    := cgg_nil_pid;
            svRemovable_kb09 := false;
            svFiller2_kb09   := false;
            svTimeout_kb09   := 0;
            svFiller3_kb09   := 0;
            IF  i < g01maxservertask
            THEN
                svNextIdle_kb09 := i + 1
            ELSE
                svNextIdle_kb09 := 0
            (*ENDIF*) 
            END;
        (*ENDWITH*) 
    (*ENDFOR*) 
    kb90_Glob.glServerFirstIdle_kb09 := 1;
    kb90_Glob.glServerStaticCnt_kb09 := 0
    END;
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'DYNP_K90_DISTRIB       :', AllocSum);
(* *)
;
(* -----  I N I T  ----- *)
IF  Trans.trError_gg00 = e_ok
THEN
    FOR i := 1 TO kb90_MessCache.mcMdescMaxItems_kb09 DO
        SAPDB_PascalFill ('VKB90 ',   1,
              sizeof (kb90_MessCache.mcMdescList_kb09^[i]),
              @kb90_MessCache.mcMdescList_kb09^[i], 1, sizeof (tkb09_MessDesc), chr (0),
              Trans.trError_gg00);
    (*ENDFOR*) 
(*ENDIF*) 
IF  Trans.trError_gg00 = e_ok
THEN
    BEGIN
    FOR i := 1 TO g01maxservertask DO
        kb90_Glob.glServerList_kb09^[i].svMdesc_kb09 := NIL;
    (*ENDFOR*) 
    kb90init_server_manager (Trans.trTaskId_gg00);
    END
ELSE
    g01abort (csp3_no_more_memory, csp3_n_distribution,
          'no more memory          ', AllocSum);
(*ENDIF*) 
vendexcl (Trans.trTaskId_gg00, g08server)
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90child_reply (
            VAR mblock           : tgg00_MessBlock;
            ServerIndex          : tsp00_Int2;
            VAR ChildTrans       : tgg00_TransChild);
 
VAR
      mdesc  : tkb09_MessDescPtr;
      parent : tkb09_ParentDescPtr;
 
BEGIN
(* I'm returning to my parent                     PTS 1104043 JA 1999-10-08 *)
mblock.mb_trns^.trError_gg00 := e_ok;
vbegexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
(**)
mdesc := kb90_Glob.glServerList_kb09^[ServerIndex].svMdesc_kb09;
&ifdef TRACE
t01msgcheck ('K90CHILD_REPLY: bad comm_state',
      (mdesc^.mdCommState_kb09 = csLocalExecution_ekb09),
      ord (mdesc^.mdCommState_kb09));
&endif
IF  NOT mblock.mb_reply
THEN
    (* "no_reply" was set in k90req_child *)
    BEGIN
&   ifdef TRACE
    t01name (kb_dist, 'MSG NOT REPLIED   ');
&   endif
    k96free_mdesc (kb90_MessCache, mdesc)
    END
ELSE
    BEGIN
    mdesc^.mdMessHead_kb09.mhTrans_kb09  := ChildTrans;
    mdesc^.mdMessHead_kb09.mhMblock_kb09 := mblock.mb_header;
    mdesc^.mdTransferLen_kb09            := sizeof(mdesc^.mdMessHead_kb09);
    mdesc^.mdCommState_kb09              := csReplyLocalChild_ekb09;
    IF  (mblock.mb_qual_len > 0) OR
        (mblock.mb_data_len > 0)
    THEN
        k96to_mdesc_move (kb90_MessCache, mblock, mdesc);
    (*ENDIF*) 
    IF  mblock.mb_trns^.trError_gg00 <> e_ok
    THEN
        BEGIN
        mdesc^.mdMessHead_kb09.mhMblock_kb09.mb_qual_len  := 0;
        mdesc^.mdMessHead_kb09.mhMblock_kb09.mb_data_len  := 0;
        mdesc^.mdMessHead_kb09.mhTrans_kb09.tcdError_gg00 := mblock.mb_trns^.trError_gg00;
        mblock.mb_trns^.trError_gg00                      := e_ok
        END;
    (*ENDIF*) 
    kb90parent_get_or_create (mdesc^.mdParentTaskId_kb09, parent);
    IF  parent = NIL
    THEN
        mblock.mb_trns^.trError_gg00 := e_too_many_child_requests;
    (*ENDIF*) 
    IF  mblock.mb_trns^.trError_gg00 = e_ok
    THEN
        BEGIN
        mdesc^.mdNext_kb09        := parent^.prMdescFirst_kb09;
        parent^.prMdescFirst_kb09 := mdesc;
        IF  (mblock.mb_trns^.trError_gg00 = e_ok) AND parent^.prRcvWaiting_kb09
        THEN
            BEGIN
            parent^.prRcvWaiting_kb09 := false;
            (* resume the PARENT process ... *)
&           ifdef TRACE
            t01int4 (kb_net, 'RESUMEparent', parent^.prTaskId_kb09);
&           endif
            (*************************************************)
            vresume (parent^.prTaskId_kb09);
            (*************************************************)
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 <> e_ok
THEN
    k96free_mdesc (kb90_MessCache, mdesc);
(*ENDIF*) 
kb90_Glob.glServerList_kb09^[ServerIndex].svMdesc_kb09 := NIL;
&ifdef TRACE
t01p2int4 (kb_net, 'DropReqCnt  ', kb90_Glob.glDropFileReqCnt_kb09
      ,            'DropFileTask', kb90_Glob.glDropFileTask_kb09);
t01p2int4 (kb_net, 'ServReserved', kb90_Glob.glServerReserved_kb09
      ,            'ServBusyCnt ', kb90_Glob.glServerBusyCnt_kb09);
&endif
IF  (kb90_Glob.glDropFileReqCnt_kb09 > 0          ) AND
    (kb90_Glob.glDropFileTask_kb09   = cgg_nil_pid) AND
    (g01maxservertask - kb90_Glob.glServerReserved_kb09 - kb90_Glob.glServerBusyCnt_kb09 +1 > 0)
THEN
    (* PTS 1105291 JA 2000-01-07 *)
    kb90child_prefix_destroy_files (mblock.mb_trns^);
(*ENDIF*) 
vendexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
&ifdef TRACE
t01basis_error (kb_dist, 'end ch_reply', mblock.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90clear_netserver (VAR Trans : tgg00_TransContext);
 
VAR
      i            : integer;
      count        : integer;
      CurrInterval : tsp00_Int4;
      CurrTime     : tsp00_Int4;
      DummyMsec    : tsp00_Int4;
 
BEGIN
Trans.trError_gg00 := e_ok;
vclock (CurrTime, DummyMsec);
vbegexcl (Trans.trTaskId_gg00, g08server);
IF  kb90_Glob.glTimeLastClear_kb09 > 0
THEN
    CurrInterval := CurrTime - kb90_Glob.glTimeLastClear_kb09
ELSE
    CurrInterval := cgg04_timeout_interval;
(*ENDIF*) 
kb90_Glob.glTimeLastClear_kb09 := CurrTime;
IF  (Trans.trError_gg00 = e_ok) AND
    (kb90_Glob.glServerStaticCnt_kb09 <= g01maxservertask)
THEN
    BEGIN
    count := 0;
    i     := kb90_Glob.glServerFirstIdle_kb09;
    WHILE (i > 0) AND (count <= g01maxservertask) DO
        WITH kb90_Glob.glServerList_kb09^[i] DO
            BEGIN
            count := count + 1;
            IF  svRemovable_kb09
            THEN
                BEGIN
                svTimeout_kb09 := svTimeout_kb09 - CurrInterval;
                IF  svTimeout_kb09 <= 0
                THEN
                    BEGIN
&                   ifdef TRACE
                    t01p2int4 (kb_dist, 'VKILL    pid', svTaskId_kb09
                          ,             'server index', i);
&                   endif
                    vkill (svTaskId_kb09);
                    svTaskId_kb09    := cgg_nil_pid;
                    svRemovable_kb09 := false;
                    svTimeout_kb09   := 0
                    END
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            i := svNextIdle_kb09;
            END;
        (*ENDWITH*) 
    (*ENDWHILE*) 
    IF  count > g01maxservertask
    THEN
        (* bad idle_list *)
        Trans.trError_gg00 := e_net_error
    (*ENDIF*) 
    END;
(*ENDIF*) 
vendexcl (Trans.trTaskId_gg00, g08server);
END;
 
(* PTS 1104043 JA 1999-10-08 'k90 discard request' removed *)
(*------------------------------*) 
 
PROCEDURE
      k90dump_netserver (
            VAR HostFile  : tgg00_VfFileref;
            VAR buf       : tsp00_Page;
            VAR OutPno    : tsp00_Int4;
            VAR OutPos    : integer;
            VAR HostError : tsp00_VfReturn;
            VAR ErrorText : tsp00_ErrText);
 
CONST
      MARK_K90GLOB   = 'K90GLOB ';
      CODE_K90GLOB   = 1601;
      MARK_K90CACHE  = 'K90CACHE';
      CODE_K90CACHE  = 1602;
      MARK_K90MDESC  = 'K90MDESC';
      CODE_K90MDESC  = 1603;
      MARK_K90MBODY  = 'K90MBODY';
      CODE_K90MBODY  = 1605;
      MARK_K90PARENT = 'K90PRENT';
      CODE_K90PARENT = 1606;
      MARK_K90SERVER = 'K90SERV ';
      CODE_K90SERVER = 1608;
 
VAR
      MoveErr  : tgg00_BasisError; (* dummy error *)
      i2       : tsp00_IntMapC2;
      i        : integer;
      DumpLen  : integer;
      DumpAddr : tsp00_Addr;
 
BEGIN
(* CRASH: outside netserver region *)
HostError := vf_ok;
MoveErr   := e_ok;
(* -----  K 9 0 G L O B  ----- *)
g01new_dump_page (HostFile, buf, OutPno, OutPos, HostError, ErrorText);
IF  HostError = vf_ok
THEN
    BEGIN
    DumpLen := sizeof (kb90_Glob);
    kb90dump_header (HostFile, DumpLen, MARK_K90GLOB, CODE_K90GLOB,
          buf, OutPno, OutPos, HostError, ErrorText)
    END;
(*ENDIF*) 
IF  HostError = vf_ok
THEN
    BEGIN
    g10mv ('VKB90 ',   2,
          sizeof (kb90_Glob), sizeof (buf),
          @kb90_Glob, 1, @buf, OutPos,
          sizeof (kb90_Glob), MoveErr);
    MoveErr := e_ok;  (* ignore error *)
    OutPos  := OutPos + sizeof (kb90_Glob)
    END;
(* -----  K 9 0 C A C H E  ----- *)
(*ENDIF*) 
IF  HostError = vf_ok
THEN
    BEGIN
    DumpLen := sizeof (kb90_MessCache);
    kb90dump_header (HostFile, DumpLen, MARK_K90CACHE, CODE_K90CACHE,
          buf, OutPno, OutPos, HostError, ErrorText)
    END;
(*ENDIF*) 
IF  HostError = vf_ok
THEN
    BEGIN
    g10mv ('VKB90 ',   3,
          sizeof (kb90_MessCache), sizeof (buf),
          @kb90_MessCache, 1, @buf, OutPos,
          sizeof (kb90_MessCache), MoveErr);
    MoveErr := e_ok;  (* ignore error *)
    OutPos  := OutPos + sizeof (kb90_MessCache)
    END;
(* -----  K 9 0 M D E S C  ----- *)
(*ENDIF*) 
i := 1;
WHILE (HostError = vf_ok)
      AND (i <= kb90_MessCache.mcMdescMaxItems_kb09) DO
    BEGIN
    IF  true OR (kb90_MessCache.mcMdescList_kb09^[i].mdCommState_kb09 <> csFree_ekb09)
    THEN
        BEGIN
        DumpLen := INT2_MXSP00  (* index *)
              +    sizeof (DumpAddr)
              +    sizeof (tkb09_MessDesc);
        kb90dump_header (HostFile, DumpLen, MARK_K90MDESC,
              CODE_K90MDESC, buf, OutPno, OutPos, HostError, ErrorText);
        IF  HostError = vf_ok
        THEN
            BEGIN
            i2.mapInt_sp00 := i;
            buf [OutPos  ] := i2.mapC2_sp00 [1];
            buf [OutPos+1] := i2.mapC2_sp00 [2];
            OutPos         := OutPos + 2;
            DumpAddr       := @kb90_MessCache.mcMdescList_kb09^[i];
            g10mv ('VKB90 ',   4,
                  sizeof (DumpAddr), sizeof (buf),
                  @DumpAddr, 1, @buf, OutPos,
                  sizeof (DumpAddr), MoveErr);
            MoveErr := e_ok;  (* ignore error *)
            OutPos  := OutPos + sizeof (DumpAddr);
            g10mv ('VKB90 ',   5,
                  sizeof (tkb09_MessDesc), sizeof (buf),
                  @kb90_MessCache.mcMdescList_kb09^[i], 1,
                  @buf, OutPos,
                  sizeof (tkb09_MessDesc), MoveErr);
            MoveErr := e_ok;  (* ignore error *)
            OutPos  := OutPos + sizeof (tkb09_MessDesc)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
(* -----  K 9 0 M B O D Y  ----- *)
i := 1;
WHILE (HostError = vf_ok)
      AND (i <= g01cache_size (cachServerMbody_egg04)) DO
    BEGIN
    IF  true OR (kb90_MessCache.mcMbodyList_kb09^[i].mbyBufLen_kb09 <> 0)
    THEN
        BEGIN
        DumpLen := INT2_MXSP00  (* index *)
              +    sizeof (DumpAddr)
              +    sizeof (tkb09_MessBodyDesc);
        kb90dump_header (HostFile, DumpLen, MARK_K90MBODY,
              CODE_K90MBODY, buf, OutPno, OutPos, HostError, ErrorText);
        IF  HostError = vf_ok
        THEN
            BEGIN
            i2.mapInt_sp00 := i;
            buf [OutPos  ] := i2.mapC2_sp00 [1];
            buf [OutPos+1] := i2.mapC2_sp00 [2];
            OutPos         := OutPos + 2;
            DumpAddr       := @kb90_MessCache.mcMbodyList_kb09^[i];
            g10mv ('VKB90 ',   6,
                  sizeof (DumpAddr), sizeof (buf),
                  @DumpAddr, 1, @buf, OutPos,
                  sizeof (DumpAddr), MoveErr);
            MoveErr := e_ok;  (* ignore error *)
            OutPos  := OutPos + sizeof (DumpAddr);
            g10mv ('VKB90 ',   7,
                  sizeof (tkb09_MessBodyDesc), sizeof (buf),
                  @kb90_MessCache.mcMbodyList_kb09^[i], 1,
                  @buf, OutPos,
                  sizeof (tkb09_MessBodyDesc), MoveErr);
            MoveErr := e_ok;  (* ignore error *)
            OutPos  := OutPos + sizeof (tkb09_MessBodyDesc)
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
(* -----  K 9 0 P A R E N T  ----- *)
i := 1;
WHILE (HostError = vf_ok) AND (i <= kb90_Glob.glParentMaxItems_kb09) DO
    BEGIN
    DumpLen := INT2_MXSP00  (* index *)
          +    sizeof (DumpAddr)
          +    sizeof (tkb09_ParentDesc)
          +    sizeof (DumpAddr);           (* PTS 1106527 JA 2000-05-05 *)
    kb90dump_header (HostFile, DumpLen, MARK_K90PARENT, CODE_K90PARENT,
          buf, OutPno, OutPos, HostError, ErrorText);
    IF  HostError = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00 := i;
        buf [OutPos  ] := i2.mapC2_sp00 [1];
        buf [OutPos+1] := i2.mapC2_sp00 [2];
        OutPos         := OutPos + 2;
        DumpAddr       := @kb90_Glob.glParentList_kb09^[i];
        g10mv ('VKB90 ',   8,
              sizeof (DumpAddr), sizeof (buf),
              @DumpAddr, 1, @buf, OutPos,
              sizeof (DumpAddr), MoveErr);
        MoveErr := e_ok;  (* ignore error *)
        OutPos  := OutPos + sizeof (DumpAddr);
        g10mv ('VKB90 ',   9,
              sizeof (tkb09_ParentDesc), sizeof (buf),
              @kb90_Glob.glParentList_kb09^[i], 1,
              @buf, OutPos, sizeof (tkb09_ParentDesc),
              MoveErr);
        MoveErr := e_ok;  (* ignore error *)
        OutPos  := OutPos + sizeof (tkb09_ParentDesc);
        IF  kb90_Glob.glParentHash_kb09^[i] = NIL
        THEN
            DumpAddr := NIL
        ELSE
            DumpAddr := @kb90_Glob.glParentHash_kb09^[i];
        (*ENDIF*) 
        g10mv ('VKB90 ',  10,
              sizeof (DumpAddr), sizeof (buf),
              @DumpAddr, 1, @buf, OutPos,
              sizeof (DumpAddr), MoveErr);
        MoveErr := e_ok;  (* ignore error *)
        OutPos  := OutPos + sizeof (DumpAddr);
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
(* -----  K 9 0 S E R V  ----- *)
i := 1;
WHILE (HostError = vf_ok) AND (i <= g01maxservertask) DO
    BEGIN
    DumpLen := INT2_MXSP00  (* index *)
          +    sizeof (DumpAddr)
          +    sizeof (tkb09_ServerDesc);
    kb90dump_header (HostFile, DumpLen, MARK_K90SERVER, CODE_K90SERVER,
          buf, OutPno, OutPos, HostError, ErrorText);
    IF  HostError = vf_ok
    THEN
        BEGIN
        i2.mapInt_sp00 := i;
        buf [OutPos  ] := i2.mapC2_sp00 [1];
        buf [OutPos+1] := i2.mapC2_sp00 [2];
        OutPos         := OutPos + 2;
        DumpAddr       := @kb90_Glob.glServerList_kb09^[i];
        g10mv ('VKB90 ',  11,
              sizeof (DumpAddr), sizeof (buf),
              @DumpAddr, 1, @buf, OutPos,
              sizeof (DumpAddr), MoveErr);
        MoveErr := e_ok;  (* ignore error *)
        OutPos  := OutPos + sizeof (DumpAddr);
        g10mv ('VKB90 ',  12,
              sizeof (tkb09_ServerDesc), sizeof (buf),
              @kb90_Glob.glServerList_kb09^[i], 1, @buf, OutPos,
              sizeof (tkb09_ServerDesc), MoveErr);
        MoveErr := e_ok;  (* ignore error *)
        OutPos  := OutPos + sizeof (tkb09_ServerDesc)
        END;
    (*ENDIF*) 
    i := i + 1
    END;
(*ENDWHILE*) 
IF  (OutPos <> 1) AND (HostError = vf_ok)
THEN
    g01new_dump_page (HostFile, buf, OutPno, OutPos, HostError, ErrorText)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION (* PTS 1000437 UH *)
      k90free_requests (TaskId : tsp00_TaskId;
            mtype              : tgg00_MessType;
            InRegion           : boolean) : tsp00_Int4;
 
BEGIN
IF  InRegion
THEN
    BEGIN
&   ifdef TRACE
    g08excl_check (TaskId, g08server);
&   endif
    END
ELSE
    vbegexcl (TaskId, g08server);
(*ENDIF*) 
WITH kb90_MessCache DO
    k90free_requests := g01calc_usable_desc (mtype, mcMdescMaxItems_kb09 - mcMdescCnt_kb09);
(*ENDWITH*) 
IF  NOT InRegion
THEN
    vendexcl (TaskId, g08server)
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90rcv_child (
            VAR mblock         : tgg00_MessBlock;
            VAR ChildTrans     : tgg00_TransChild);
 
VAR
      ErrTextType : tgg00_ErrorText;
      DummyErr    : tgg00_BasisError;
      ErrTextLen  : integer;
      CurrHash    : tkb09_ParentDescPtr;
      parent      : tkb09_ParentDescPtr;
      mdesc       : tkb09_MessDescPtr;
      ErrorText   : tsp00_ErrText;
 
BEGIN
(* I'm waiting for the return of my child's *)
mblock.mb_trns^.trError_gg00 := e_ok;
ErrTextLen := 0;
vbegexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
kb90parent_get_or_create (mblock.mb_trns^.trTaskId_gg00, parent);
IF  parent = NIL
THEN
    mblock.mb_trns^.trError_gg00 := e_too_many_child_requests
ELSE
    IF  parent^.prMdescFirst_kb09 = NIL
    THEN
        kb90parent_wait (mblock.mb_trns^, parent);
    (*ENDIF*) 
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    mdesc                     := parent^.prMdescFirst_kb09;
    parent^.prMdescFirst_kb09 := mdesc^.mdNext_kb09;
    mdesc^.mdNext_kb09        := NIL;
    IF  parent^.prMdescFirst_kb09 = NIL
    THEN
        (* remove parent *)
        BEGIN
        parent^.prTaskId_kb09     := cgg_nil_pid;
        parent^.prRcvWaiting_kb09 := false;
        parent^.prRcvTimeout_kb09 := 0;
        IF  kb90_Glob.glParentHash_kb09^[parent^.prHashIndex_kb09] = parent
        THEN
            kb90_Glob.glParentHash_kb09^[parent^.prHashIndex_kb09] := parent^.prNext_kb09
        ELSE
            BEGIN
            CurrHash := kb90_Glob.glParentHash_kb09^[parent^.prHashIndex_kb09];
            WHILE CurrHash^.prNext_kb09 <> parent DO
                CurrHash := CurrHash^.prNext_kb09;
            (*ENDWHILE*) 
            CurrHash^.prNext_kb09 := parent^.prNext_kb09
            END;
        (*ENDIF*) 
        parent^.prTaskId_kb09            := cgg_nil_pid;
        parent^.prRcvWaiting_kb09        := false;
        parent^.prRcvTimeout_kb09        := 0;
        parent^.prHashIndex_kb09         := 0;
        parent^.prNext_kb09              := kb90_Glob.glParentFirstFree_kb09;
        kb90_Glob.glParentFirstFree_kb09 := parent
        END;
    (*ENDIF*) 
    ChildTrans       := mdesc^.mdMessHead_kb09.mhTrans_kb09;
    mblock.mb_header := mdesc^.mdMessHead_kb09.mhMblock_kb09;
    IF  (ChildTrans.tcdError_gg00 <> e_ok)
        AND
        (mblock.mb_type  = m_return_error) AND
        (mblock.mb_type2 = mm_string     )
    THEN
        BEGIN
        IF  mblock.mb_data_len > 1
        THEN
            k96errtext_from_mdesc (mdesc, ErrTextLen,
                  ErrTextType, ErrorText, mblock.mb_trns^.trError_gg00);
        (*ENDIF*) 
        mblock.mb_data_len := 0;
        mblock.mb_type2    := mm_nil
        END
    ELSE
        IF  (mblock.mb_qual_len > 0) OR
            (mblock.mb_data_len > 0)
        THEN
            k96move_from_mdesc (mblock, mdesc);
        (*ENDIF*) 
    (*ENDIF*) 
    IF  mdesc <> NIL
    THEN
        k96free_mdesc (kb90_MessCache, mdesc)
    (*ENDIF*) 
    END;
(*ENDIF*) 
vendexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
IF  (mblock.mb_trns^.trError_gg00 = e_ok) AND (ErrTextLen > 0)
THEN
    b06put_errtxt (mblock.mb_trns^, mblock.mb_trns^.trTaskId_gg00,
          ErrTextLen, ErrTextType, ChildTrans.tcdError_gg00, ErrorText, DummyErr);
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 <> e_ok
THEN
    ChildTrans := mblock.mb_trans_child^; (* security init *)
(*ENDIF*) 
;
&ifdef TRACE
t01basis_error (kb_dist, 'end rcv_chld', mblock.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90send (
            VAR mblock     : tgg00_MessBlock;
            VAR ChildTrans : tgg00_TransChild);
 
VAR
      mdesc : tkb09_MessDescPtr;
 
BEGIN
mblock.mb_trns^.trError_gg00 := e_ok;
mdesc := NIL;
&ifdef TRACE
t01messblock (kb_dist, 'SEND BLOCK  ', mblock);
&endif
vbegexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
IF  k90free_requests (mblock.mb_trns^.trTaskId_gg00,
    mblock.mb_type, IN_SERVER_REGION) <= 0 (* PTS 1000437 UH / PTS 1105291 JA 2000-01-07 *)
THEN
    mblock.mb_trns^.trError_gg00 := e_too_many_net_requests
ELSE
    k96new_mdesc (mblock.mb_trns^, kb90_MessCache, mdesc, mblock.mb_trns^.trTaskId_gg00);
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    mdesc^.mdCommState_kb09              := csReqLocalChild_ekb09;
    mdesc^.mdMessHead_kb09.mhMblock_kb09 := mblock.mb_header;
    mdesc^.mdMessHead_kb09.mhTrans_kb09  := ChildTrans;
    mdesc^.mdTransferLen_kb09            := sizeof (mdesc^.mdMessHead_kb09);
    IF  (mblock.mb_qual_len > 0) OR
        (mblock.mb_data_len > 0)
    THEN
        k96to_mdesc_move (kb90_MessCache, mblock, mdesc)
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    mdesc^.mdNext_kb09 := NIL;
    IF  kb90_Glob.glLastServerJob_kb09 <> NIL
    THEN
        kb90_Glob.glLastServerJob_kb09^.mdNext_kb09 := mdesc
    ELSE
        kb90_Glob.glFirstServerJob_kb09 := mdesc;
    (*ENDIF*) 
    kb90_Glob.glLastServerJob_kb09 := mdesc;
    IF  kb90_Glob.glServerFirstIdle_kb09 > 0
    THEN
        kb90idle_server_start (mblock.mb_trns^)
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 <> e_ok
THEN
    k96free_mdesc (kb90_MessCache, mdesc);
(*ENDIF*) 
vendexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
&ifdef TRACE
t01basis_error (kb_dist, 'end send    ', mblock.mb_trns^.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90send_prefix_destroy_files (VAR Trans : tgg00_TransContext);
 
VAR
      mdesc        : tkb09_MessDescPtr;
      TransPtr     : tgg00_UnivTransPtr;
      RecPtr       : tgg00_RecPtr;
      OverflowFile : tgg00_FileId;
      OverflowRec  : tkb09_TransIdRec;
 
BEGIN
(* PTS 1105291 JA 2000-01-07 *)
Trans.trError_gg00 := e_ok;
mdesc              := NIL;
vbegexcl (Trans.trTaskId_gg00, g08server);
IF  g01maxservertask - kb90_Glob.glServerReserved_kb09 - kb90_Glob.glServerBusyCnt_kb09 > 0
THEN
    Trans.trError_gg00 := e_too_many_net_requests
ELSE
    BEGIN
    k96new_mdesc (Trans, kb90_MessCache, mdesc, Trans.trTaskId_gg00);
    IF  Trans.trError_gg00 = e_ok
    THEN
        BEGIN
        TransPtr                             := @Trans;
        mdesc^.mdMessHead_kb09.mhTrans_kb09  := TransPtr^.utrChild;
        mdesc^.mdCommState_kb09              := csReqLocalChild_ekb09;
        mdesc^.mdTransferLen_kb09            := sizeof (mdesc^.mdMessHead_kb09);
        WITH mdesc^.mdMessHead_kb09.mhMblock_kb09 DO
            BEGIN
            mb_qual_len   := 0;
            mb_data_len   := 0;
            mb_src_site   := cgg04_nil_site;
            mb_reply      := false;
            mb_type       := m_drop;
            mb_type2      := mm_parallel;
            mb_struct     := mbs_nil;
            mb_fill1      := false
            END;
        (*ENDWITH*) 
        mdesc^.mdNext_kb09 := NIL;
        IF  kb90_Glob.glLastServerJob_kb09 <> NIL
        THEN
            kb90_Glob.glLastServerJob_kb09^.mdNext_kb09 := mdesc
        ELSE
            kb90_Glob.glFirstServerJob_kb09 := mdesc;
        (*ENDIF*) 
        kb90_Glob.glLastServerJob_kb09 := mdesc;
        IF  kb90_Glob.glServerFirstIdle_kb09 > 0
        THEN
            kb90idle_server_start (Trans)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  Trans.trError_gg00 <> e_ok
    THEN
        k96free_mdesc (kb90_MessCache, mdesc)
    (*ENDIF*) 
    END;
(*ENDIF*) 
vendexcl (Trans.trTaskId_gg00, g08server);
IF  Trans.trError_gg00 = e_too_many_net_requests
THEN
    (* append transid to drop_file *)
    BEGIN
    Trans.trError_gg00 := e_ok; (* reset *)
    WITH OverflowRec, OverflowRec.tirHeader_kb09 DO
        BEGIN
        hrecKeyLen_gg00       := sizeof (tirTransNo_kb09) + sizeof (tirLastKeyByte_kb09);
        hrecLen_gg00          := sizeof (tirHeader_kb09 ) + hrecKeyLen_gg00;
        hrecVarcolOffset_gg00 := 0;
        hrecVarcolCnt_gg00    := 0;
        tirTransNo_kb09       := Trans.trWriteTransId_gg00;
        tirLastKeyByte_kb09   := chr (1)
        END;
    (*ENDWITH*) 
    RecPtr := @OverflowRec;
    kb90build_overflow_file_id (OverflowFile);
    b01filestate (Trans, OverflowFile);
    IF  Trans.trError_gg00 = e_file_not_found
    THEN
        BEGIN
        Trans.trError_gg00 := e_ok;
        b01tcreate_file (Trans, OverflowFile); (* file exists until next shutdown *)
        END;
    (*ENDIF*) 
    IF  Trans.trError_gg00 = e_ok
    THEN
        b02add_record (Trans, OverflowFile, RecPtr^);
    (*ENDIF*) 
    IF  Trans.trError_gg00 = e_ok
    THEN
        BEGIN
        vbegexcl (Trans.trTaskId_gg00, g08server);
        kb90_Glob.glDropFileReqCnt_kb09 := kb90_Glob.glDropFileReqCnt_kb09 + 1;
        IF  (kb90_Glob.glServerFirstIdle_kb09 > 0)
            AND
            (g01maxservertask - kb90_Glob.glServerReserved_kb09 - kb90_Glob.glServerBusyCnt_kb09  > 0)
        THEN
            kb90idle_server_start (Trans);
        (*ENDIF*) 
        vendexcl (Trans.trTaskId_gg00, g08server);
        END;
    (*ENDIF*) 
    Trans.trError_gg00 := e_ok; (* ignore errors *)
    END;
&ifdef TRACE
(*ENDIF*) 
t01basis_error (kb_dist, 'end send_pre', Trans.trError_gg00);
&endif
END;
 
(*------------------------------*) 
 
PROCEDURE
      k90server_init (
            VAR Trans           : tgg00_TransContext;
            VAR ServerIndex     : tsp00_Int2;
            VAR IsDynamic       : boolean);
 
VAR
      curr : integer;
 
BEGIN
Trans.trError_gg00 := e_ok;
kb90_Glob.glServerBusyCnt_kb09 :=
      kb90_Glob.glServerBusyCnt_kb09 + 1; (* PTS 1105291 JA 2000-01-07 *)
&ifdef TRACE
g08excl_check (Trans.trTaskId_gg00, g08server);
&endif
ServerIndex := 0;
IsDynamic   := false;
curr        := 1;
(* search dynamic server: TaskId already inserted by receiver *)
REPEAT
    IF  kb90_Glob.glServerList_kb09^[curr].svTaskId_kb09 = Trans.trTaskId_gg00
    THEN
        BEGIN
        ServerIndex := curr;
        IsDynamic   := true
        END
    ELSE
        curr := curr + 1
    (*ENDIF*) 
UNTIL
    (ServerIndex > 0) OR (curr > g01maxservertask);
(*ENDREPEAT*) 
IF  NOT IsDynamic
THEN
    BEGIN
    curr := 1;
    WHILE (ServerIndex <= 0) AND (curr <= g01maxservertask) DO
        (* search unused server desc *)
        IF  kb90_Glob.glServerList_kb09^[curr].svTaskId_kb09 = cgg_nil_pid
        THEN
            (* insert static server *)
            WITH kb90_Glob DO
                BEGIN
                glServerStaticCnt_kb09 := glServerStaticCnt_kb09 + 1;
                ServerIndex            := curr;
                glServerList_kb09^[curr].svTaskId_kb09 := Trans.trTaskId_gg00
                END
            (*ENDWITH*) 
        ELSE
            curr := curr + 1;
        (*ENDIF*) 
    (*ENDWHILE*) 
    IF  ServerIndex <= 0
    THEN
        Trans.trError_gg00 := e_no_servers
    (*ENDIF*) 
    END;
(*ENDIF*) 
IF  Trans.trError_gg00 <> e_ok
THEN
    gg999Offline (Trans.trError_gg00);
(*ENDIF*) 
END;
 
(* PTS 1003033 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      k90sreceive_server (
            VAR mblock              : tgg00_MessBlock;
            ServerIndex             : tsp00_Int2;
            AlreadyIdle             : boolean;
            VAR ChildTrans          : tgg00_TransChild);
 
VAR
      received : boolean;
      TryAgain : boolean;
      curr     : tsp00_Int2;
      prev     : tsp00_Int2;
      mdesc    : tkb09_MessDescPtr;
      NetTrace : tsp00_Line;
 
BEGIN
mblock.mb_trns^.trError_gg00 := e_ok;
vbegexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
(* PTS 1103743 JA 1999-08-25 *)
kb90_Glob.glServerCallCnt_kb09 := kb90_Glob.glServerCallCnt_kb09 + ONE_8BYTE_CNT_GG04;
mdesc    := NIL;
received := false;
TryAgain := false;
WHILE NOT received AND (mblock.mb_trns^.trError_gg00 = e_ok) DO
    BEGIN
    IF  g01vtrace.vtrAll_gg00
    THEN
        BEGIN
        NetTrace [1] := chr(0);
        NetTrace [2] := chr(ord(sp1ce_ok));
        (* third byte: is static server *)
        NetTrace [3] := chr (ord (ServerIndex <= kb90_Glob.glServerStaticCnt_kb09));
        b120InsertTrace (mblock.mb_trns^, kb_net, vttKbServer_egg00, 3, @NetTrace);
        mblock.mb_trns^.trError_gg00 := e_ok
        END;
    (*ENDIF*) 
    ;
&   ifdef TRACE
    t01p2int4 (kb_net, 'DropReqCnt  ', kb90_Glob.glDropFileReqCnt_kb09
          ,            'DropFileTask', kb90_Glob.glDropFileTask_kb09);
    t01p2int4 (kb_net, 'ServReserved', kb90_Glob.glServerReserved_kb09
          ,            'ServBusyCnt ', kb90_Glob.glServerBusyCnt_kb09);
    t01int4   (kb_net, 'maxservtask ', g01maxservertask);
&   endif
    WHILE (kb90_Glob.glFirstServerJob_kb09 = NIL        ) AND     (* PTS 1105291 JA 2000-01-07 *)
          (kb90_Glob.glDropFileReqCnt_kb09 > 0          ) AND
          (kb90_Glob.glDropFileTask_kb09   = cgg_nil_pid) AND
          (g01maxservertask
          - kb90_Glob.glServerReserved_kb09 - kb90_Glob.glServerBusyCnt_kb09 +1 > 0) DO
        kb90child_prefix_destroy_files (mblock.mb_trns^);
    (*ENDWHILE*) 
    IF  kb90_Glob.glFirstServerJob_kb09 <> NIL
    THEN
        (* PTS 1104043 JA 1999-10-08 *)
        BEGIN
        received                        := true;
        mdesc                           := kb90_Glob.glFirstServerJob_kb09;
        kb90_Glob.glFirstServerJob_kb09 := mdesc^.mdNext_kb09;
        mdesc^.mdNext_kb09              := NIL;
        IF  kb90_Glob.glFirstServerJob_kb09 = NIL
        THEN
            kb90_Glob.glLastServerJob_kb09 := NIL
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  NOT received AND (mblock.mb_trns^.trError_gg00 = e_ok)
    THEN
        BEGIN
        IF  NOT AlreadyIdle OR TryAgain
        THEN
            (* insert into list of idle servers *)
            WITH kb90_Glob.glServerList_kb09^[ServerIndex] DO
                BEGIN
                svMdesc_kb09 := NIL;
                IF  ServerIndex <= kb90_Glob.glServerStaticCnt_kb09
                THEN
                    (* static server: insert at top of list *)
                    BEGIN
&                   ifdef TRACE
                    t01msgcheck ('K90SRCV: server already idle  ',
                          kb90_Glob.glServerFirstIdle_kb09 <> ServerIndex,
                          ServerIndex);
&                   endif
                    svNextIdle_kb09 := kb90_Glob.glServerFirstIdle_kb09;
                    kb90_Glob.glServerFirstIdle_kb09 := ServerIndex
                    END
                ELSE
                    (* dynamic server: insert behind static server *)
                    BEGIN
                    svTimeout_kb09   := TIMEOUT_SERVER;
                    svRemovable_kb09 := true;
                    IF  (kb90_Glob.glServerFirstIdle_kb09 <= 0)
                        OR
                        (kb90_Glob.glServerFirstIdle_kb09 >
                        kb90_Glob.glServerStaticCnt_kb09)
                    THEN
                        BEGIN
                        svNextIdle_kb09                  := kb90_Glob.glServerFirstIdle_kb09;
                        kb90_Glob.glServerFirstIdle_kb09 := ServerIndex
                        END
                    ELSE
                        BEGIN
                        curr := kb90_Glob.glServerFirstIdle_kb09;
                        REPEAT
                            prev := curr;
                            curr := kb90_Glob.glServerList_kb09^[curr].svNextIdle_kb09
                        UNTIL
                            (curr <= 0) OR
                            (curr > kb90_Glob.glServerStaticCnt_kb09);
                        (*ENDREPEAT*) 
                        svNextIdle_kb09 := curr;
                        kb90_Glob.glServerList_kb09^[prev].svNextIdle_kb09 := ServerIndex
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        WITH mblock.mb_trns^ DO
            BEGIN
&           ifdef TRACE
            t01int4 (kb_dist, 'serv-SUSPEND', trTaskId_gg00);
&           endif
            kb90_Glob.glServerBusyCnt_kb09 :=
                  kb90_Glob.glServerBusyCnt_kb09 - 1; (* PTS 1105291 JA 2000-01-07 *)
            vendexcl (trTaskId_gg00, g08server);
            (*******************************************)
            vsuspend (trTaskId_gg00, 255); (* suspend reason 255 is reserved for 'No work', TSK_VSUSPEND_REASON_NO_WORK *)
            (*******************************************)
            vbegexcl (trTaskId_gg00, g08server);
            kb90_Glob.glServerBusyCnt_kb09 :=
                  kb90_Glob.glServerBusyCnt_kb09 + 1; (* PTS 1105291 JA 2000-01-07 *)
            END
        (*ENDWITH*) 
        END;
    (*ENDIF*) 
    TryAgain := NOT received
    END;
(*ENDWHILE*) 
&ifdef TRACE
IF  mblock.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    kb90tdmdesc (kb_net, 'srcv server ', true, mdesc);
    t01msgcheck ('K90SRECEIVE: invalid commstate',
          (mdesc^.mdCommState_kb09 = csReqLocalChild_ekb09),
          ord (mdesc^.mdCommState_kb09))
    END;
&endif
(*ENDIF*) 
IF  mblock.mb_trns^.trError_gg00 = e_ok
THEN
    BEGIN
    (* service request found *)
    WITH mdesc^.mdMessHead_kb09 DO
        BEGIN
        mblock.mb_header := mhMblock_kb09;
        ChildTrans       := mhTrans_kb09
        END;
    (*ENDWITH*) 
    IF  (mblock.mb_qual_len > 0) OR
        (mblock.mb_data_len > 0)
    THEN
        k96move_from_mdesc (mblock, mdesc);
    (*ENDIF*) 
    kb90_Glob.glServerList_kb09^[ServerIndex].svMdesc_kb09 := mdesc;
    mdesc^.mdCommState_kb09  := csLocalExecution_ekb09
    END;
(*ENDIF*) 
IF  mdesc <> NIL
THEN
    BEGIN
    IF  mdesc^.mdMessBody_kb09 <> NIL
    THEN
        k96free_messbody (kb90_MessCache, mdesc^.mdMessBody_kb09)
    (*ENDIF*) 
    END;
(*ENDIF*) 
vendexcl (mblock.mb_trns^.trTaskId_gg00, g08server);
&ifdef TRACE
t01basis_error (kb_dist, 'end sreceive', mblock.mb_trns^.trError_gg00);
&endif
END;
 
(* PTS 1003033 E.Z. *)
(*------------------------------*) 
 
PROCEDURE
      k90wait_until_server_finished (TaskId : tsp00_TaskId);
 
VAR
      ServerRunning : boolean;
      i             : integer;
      WaitCount     : integer;
 
BEGIN
&ifdef TRACE
g08excl_check (TaskId, g08server);
&endif
WaitCount := 0;
REPEAT
    ServerRunning := false;
    i             := 1;
    WHILE NOT ServerRunning AND (i <= g01maxservertask) DO
        IF  kb90_Glob.glServerList_kb09^[i].svMdesc_kb09 <> NIL
        THEN
            ServerRunning := true
        ELSE
            i := i + 1;
        (*ENDIF*) 
    (*ENDWHILE*) 
    IF  ServerRunning
    THEN
        BEGIN
        IF  WaitCount > TIMEOUT_RECEIVE
        THEN
            g01abort (kbServerTaskTimeout_csp03, csp3_n_net,
                  'SERVER TASK RUNNING:    ', i)
        ELSE
            BEGIN
            WaitCount := WaitCount + 1;
            vendexcl (TaskId, g08server);
            vsleep   (TaskId, 1);
            vbegexcl (TaskId, g08server);
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
UNTIL
    NOT ServerRunning
(*ENDREPEAT*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90AddToPrefixDestroyFile (
            VAR trans   : tgg00_TransContext;
            fileTransId : tgg91_TransNo);
 
VAR
      pRec         : tgg00_RecPtr;
      overflowRec  : tkb09_TransIdRec;
      overflowFile : tgg00_FileId;
 
BEGIN
pRec := @overflowRec;
WITH overflowRec, overflowRec.tirHeader_kb09 DO
    BEGIN
    hrecKeyLen_gg00       := sizeof (tirTransNo_kb09) + sizeof (tirLastKeyByte_kb09);
    hrecLen_gg00          := sizeof (tirHeader_kb09 ) + hrecKeyLen_gg00;
    hrecVarcolOffset_gg00 := 0;
    hrecVarcolCnt_gg00    := 0;
    tirTransNo_kb09       := fileTransId;
    tirLastKeyByte_kb09   := chr (1)
    END;
(*ENDWITH*) 
kb90build_overflow_file_id (overflowFile);
b01filestate (trans, overflowFile);
IF  trans.trError_gg00 = e_file_not_found
THEN
    BEGIN
    trans.trError_gg00 := e_ok;
    b01tcreate_file (trans, overflowFile); (* file exists until next shutdown *)
    END;
(*ENDIF*) 
IF  trans.trError_gg00 = e_ok
THEN
    b02add_record (trans, overflowFile, pRec^);
(*ENDIF*) 
IF  trans.trError_gg00 = e_ok (* no duplicates *)
THEN
    BEGIN
    vbegexcl (trans.trTaskId_gg00, g08server);
    kb90_Glob.glDropFileReqCnt_kb09 := kb90_Glob.glDropFileReqCnt_kb09 + 1;
    vendexcl (trans.trTaskId_gg00, g08server);
    END;
(*ENDIF*) 
trans.trError_gg00 := e_ok; (* ignore errors *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90build_overflow_file_id (VAR OverflowFile : tgg00_FileId);
 
VAR
      pos : integer;
 
BEGIN
(* PTS 1105291 JA 2000-01-07 *)
OverflowFile := b01niltree_id;
WITH OverflowFile DO
    BEGIN
    fileType_gg00 := [ftsTemp_egg00, ftsConcurrent_egg00, ftsShared_egg00];
    fileTfn_gg00  := tfnTempAux_egg00;
    gg06SetDummyTrans (fileTransId_gg00);
    pos := sizeof (fileType_gg00) + sizeof (fileTfn_gg00) + sizeof (fileTransId_gg00);
    fileName_gg00 [pos] := chr (1)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90child_prefix_destroy_files (VAR Trans : tgg00_TransContext);
 
VAR
      CurrKeyPtr     : tgg00_LkeyPtr;
      OverflowRecPtr : tkb09_TransIdRecPtr;
      OverflowFile   : tgg00_FileId;
      CurrKeyRec     : tkb09_TransIdRec;
      rec            : tgg00_Rec;
 
BEGIN
(* PTS 1105291 JA 2000-01-07 *)
Trans.trError_gg00 := e_ok;
&ifdef TRACE
g08excl_check (Trans.trTaskId_gg00, g08server);
&endif
kb90_Glob.glDropFileTask_kb09 := Trans.trTaskId_gg00;
vendexcl (Trans.trTaskId_gg00, g08server);
WHILE Trans.trError_gg00 = e_ok DO
    BEGIN
    OverflowRecPtr          := @rec;
    CurrKeyPtr              := @CurrKeyRec;
    CurrKeyPtr^.keyLen_gg00 := 0;
    kb90build_overflow_file_id (OverflowFile);
    b02next_record (Trans, OverflowFile, CurrKeyPtr^, NOT INCLUSIVE, rec);
    IF  (Trans.trError_gg00 = e_ok) OR (Trans.trError_gg00 = e_key_not_found)
    THEN
        BEGIN
        Trans.trError_gg00   := e_ok;
        CurrKeyRec           := OverflowRecPtr^;
        Trans.trWriteTransId_gg00 := OverflowRecPtr^.tirTransNo_kb09;
        k53server_drop_aux_files (Trans);
        Trans.trError_gg00   := e_ok;  (* ignore errors *)
        b02del_record (Trans, OverflowFile, CurrKeyPtr^);
        Trans.trError_gg00   := e_ok;  (* ignore errors *)
        vbegexcl (Trans.trTaskId_gg00, g08server);
        kb90_Glob.glDropFileReqCnt_kb09 := kb90_Glob.glDropFileReqCnt_kb09 - 1;
        vendexcl (Trans.trTaskId_gg00, g08server);
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
Trans.trError_gg00 := e_ok;  (* reset no next record *)
vbegexcl (Trans.trTaskId_gg00, g08server);
kb90_Glob.glDropFileTask_kb09 := cgg_nil_pid;
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90dump_header (
            VAR HostFile  : tgg00_VfFileref;
            DumpLen       : integer;
            dump_mark     : tsp00_C8;
            dump_code     : tsp00_Int2;
            VAR buf       : tsp00_Page;
            VAR OutPno    : tsp00_Int4;
            VAR OutPos    : integer;
            VAR HostError : tsp00_VfReturn;
            VAR ErrorText : tsp00_ErrText);
 
CONST
      HEADER_LEN = 10;
 
VAR
      MoveErr : tgg00_BasisError; (* dummy error *)
      i2      : tsp00_IntMapC2;
 
BEGIN
MoveErr := e_ok;
IF  OutPos + HEADER_LEN + DumpLen > sizeof (buf)
THEN
    g01new_dump_page (HostFile, buf, OutPno, OutPos, HostError, ErrorText);
(*ENDIF*) 
IF  HostError = vf_ok
THEN
    BEGIN
    g10mv ('VKB90 ',  13,
          sizeof (dump_mark), sizeof (buf),
          @dump_mark, 1, @buf, OutPos,
          sizeof (dump_mark), MoveErr);
    OutPos         := OutPos + sizeof (dump_mark);
    i2.mapInt_sp00 := dump_code;
    buf [OutPos  ] := i2.mapC2_sp00 [1];
    buf [OutPos+1] := i2.mapC2_sp00 [2];
    OutPos         := OutPos + 2
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90idle_server_start (VAR Trans : tgg00_TransContext);
 
VAR
      IsOk       : boolean;
      IdleServer : tsp00_Int2;
 
BEGIN
Trans.trError_gg00 := e_ok;
&ifdef TRACE
g08excl_check (Trans.trTaskId_gg00, g08server);
&endif
IdleServer := kb90_Glob.glServerFirstIdle_kb09;
&ifdef TRACE
t01int4 (kb_dist, 'idle-serv-no', IdleServer) ;
&endif
IF  IdleServer > 0
THEN
    WITH kb90_Glob.glServerList_kb09^[IdleServer] DO
        BEGIN
        kb90_Glob.glServerFirstIdle_kb09 := svNextIdle_kb09;
        svNextIdle_kb09  := 0;
        svRemovable_kb09 := false;
        svTimeout_kb09   := 0;
        IF  svTaskId_kb09 <> cgg_nil_pid
        THEN
            BEGIN
&           ifdef TRACE
            t01int4 (kb_net, 'resuming... ', svTaskId_kb09);
&           endif
            (*****************************************)
            vresume (svTaskId_kb09);
            (*****************************************)
            END
        ELSE
            BEGIN
            IsOk := true;
            (******************************************)
            vcreate (sp2pt_server, svTaskId_kb09, IsOk);
            (******************************************)
            IF  NOT IsOk
            THEN
                Trans.trError_gg00 := e_no_servers;
&           ifdef TRACE
            (*ENDIF*) 
            IF  IsOk
            THEN
                t01p2int4 (kb_net, 'VCREATE  pid', svTaskId_kb09
                      ,            'server index', IdleServer);
&           endif
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90init_server_manager (TaskId : tsp00_TaskId);
 
VAR
      i : integer;
 
BEGIN
(* PTS 1104043 JA 1999-10-08 *)
&ifdef TRACE
g08excl_check (TaskId, g08server);
&endif
(* k90wait_until_server_finished (TaskId); HOT STAND BY - ASYNC RESTART *)
FOR i := 1 TO g01maxservertask DO
    kb90_Glob.glServerList_kb09^[i].svMdesc_kb09 := NIL;
(*ENDFOR*) 
kb90_Glob.glFirstServerJob_kb09 := NIL;
kb90_Glob.glLastServerJob_kb09  := NIL;
WITH kb90_MessCache DO
    BEGIN
    i := 1;
    WHILE i <= g01cache_size (cachServerMbody_egg04) DO
        BEGIN
        IF  i = g01cache_size (cachServerMbody_egg04)
        THEN
            mcMbodyList_kb09^[i].mbyNext_kb09 := NIL
        ELSE
            mcMbodyList_kb09^[i].mbyNext_kb09 := @mcMbodyList_kb09^[i+1];
        (*ENDIF*) 
        i := i + 1
        END;
    (*ENDWHILE*) 
    mcMbodyFirstFree_kb09 := @mcMbodyList_kb09^[1];
    mcMbodyCnt_kb09       := 0
    END;
(*ENDWITH*) 
WITH kb90_MessCache DO
    BEGIN
    mcMdescFirstFree_kb09 := NIL; (* PTS 1104043 JA 1999-10-08 *)
    mcMdescCnt_kb09       := 0;
    FOR i := kb90_MessCache.mcMdescMaxItems_kb09 DOWNTO 1 DO
        BEGIN
        mcMdescList_kb09^[i].mdFiller1_kb09 := false;
        mcMdescList_kb09^[i].mdFiller2_kb09 := 0;
        mcMdescList_kb09^[i].mdFiller3_kb09 := 0;
        k96clear_mdesc (mcMdescList_kb09^[i]);
        mcMdescList_kb09^[i].mdNext_kb09 := mcMdescFirstFree_kb09;
        mcMdescFirstFree_kb09            := @mcMdescList_kb09^[i]
        END
    (*ENDFOR*) 
    END;
(*ENDWITH*) 
FOR i := 1 TO kb90_Glob.glParentMaxItems_kb09 DO
    WITH kb90_Glob.glParentList_kb09^[i] DO
        BEGIN
        prTaskId_kb09     := 0;
        prRcvWaiting_kb09 := false;
        prRcvTimeout_kb09 := 0;
        prHashIndex_kb09  := 0;
        prMdescFirst_kb09 := NIL;
        IF  i < kb90_Glob.glParentMaxItems_kb09
        THEN
            prNext_kb09 := @kb90_Glob.glParentList_kb09^[i+1]
        ELSE
            prNext_kb09 := NIL;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDFOR*) 
kb90_Glob.glParentFirstFree_kb09 := @kb90_Glob.glParentList_kb09^[1];
FOR i := 1 TO kb90_Glob.glParentMaxItems_kb09 DO
    kb90_Glob.glParentHash_kb09^[i] := NIL
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90parent_wait (
            VAR parent_trans : tgg00_TransContext;
            parent : tkb09_ParentDescPtr);
 
BEGIN
(* PTS 1104043 JA 1999-10-08 *)
&ifdef TRACE
g08excl_check (parent_trans.trTaskId_gg00, g08server);
t01int4 (kb_net, 'PARENT suspe', parent_trans.trTaskId_gg00);
&endif
parent^.prRcvWaiting_kb09 := true;
IF  kb03Check.chkTrans_kb00
THEN
    g01check (kb90cParentWait_csp03, csp3_n_net,
          'kb90parent_wait:bad task', parent^.prTaskId_kb09,
          parent^.prTaskId_kb09 = parent_trans.trTaskId_gg00);
(*ENDIF*) 
vendexcl (parent_trans.trTaskId_gg00, g08server);
(*************************************************************)
vsuspend (parent_trans.trTaskId_gg00, 212);
(*************************************************************)
&ifdef TRACE
t01name (kb_net, 'parent RUNNING !  ');
&endif
vbegexcl (parent_trans.trTaskId_gg00, g08server)
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90parent_get_or_create (
            TaskId     : tsp00_TaskId;
            VAR parent : tkb09_ParentDescPtr);
 
VAR
      curr      : tkb09_ParentDescPtr;
      HashIndex : tsp00_Int2;
 
BEGIN
(* PTS 1104043 JA 1999-10-08 *)
&ifdef TRACE
g08check_excl (g08server);
t01int4 (kb_net, 'pid         ', TaskId);
&endif
parent := NIL;
IF  TaskId > 0
THEN
    HashIndex :=  TaskId MOD kb90_Glob.glParentMaxItems_kb09 + 1
ELSE
    HashIndex := -TaskId MOD kb90_Glob.glParentMaxItems_kb09 + 1;
(*ENDIF*) 
;
&ifdef TRACE
t01int4 (kb_net, 'HashIndex   ', HashIndex);
&endif
curr := kb90_Glob.glParentHash_kb09^[HashIndex];
WHILE curr <> NIL DO
    IF  curr^.prTaskId_kb09 = TaskId
    THEN
        BEGIN
        parent := curr;
        curr   := NIL
        END
    ELSE
        curr := curr^.prNext_kb09;
    (*ENDIF*) 
(*ENDWHILE*) 
IF  parent = NIL
THEN
    BEGIN
    parent := kb90_Glob.glParentFirstFree_kb09;
    IF  parent <> NIL
    THEN
        BEGIN
        kb90_Glob.glParentFirstFree_kb09 := parent^.prNext_kb09;
        parent^.prNext_kb09              := kb90_Glob.glParentHash_kb09^[HashIndex];
        kb90_Glob.glParentHash_kb09^[HashIndex] := parent;
        parent^.prTaskId_kb09            := TaskId;
        parent^.prRcvWaiting_kb09        := false;
        parent^.prRcvTimeout_kb09        := 0;
        parent^.prHashIndex_kb09         := HashIndex;
        parent^.prMdescFirst_kb09        := NIL
        END
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      kb90vallocate (
            length          : tsp00_Int4;
            VAR uvObjAddr   : tsp00_ObjAddr;
            VAR AllocSum    : tsp00_Int4;
            VAR e           : tgg00_BasisError);
 
VAR
      IsOk : boolean;
 
BEGIN
e        := e_ok;
IsOk     := true;
AllocSum := AllocSum + g01align (length);
vallocat (length, uvObjAddr, IsOk);
IF  NOT IsOk
THEN
    e := e_sysbuf_storage_exceeded
(*ENDIF*) 
END;
 
&ifdef TRACE
(*------------------------------*) 
 
PROCEDURE
      kb90tdmdesc (
            debug        : tgg00_Debug;
            nam          : tsp00_Sname;
            WithMbuf     : boolean;
            VAR mdesc    : tkb09_MessDescPtr);
 
BEGIN
t01name1 (debug, nam, 'MSG DESCRIPTOR    ');
t01addr  (debug, ' -mdesc addr', mdesc);
IF  (mdesc <> NIL) AND t01trace (debug)
THEN
    WITH mdesc^ DO
        BEGIN
        t01p2int4      (debug, ' -transf_len', mdTransferLen_kb09
              ,                ' -client_pid', mdParentTaskId_kb09);
        t01basis_error (debug, ' -errorstate', mdMessHead_kb09.mhTrans_kb09.tcdError_gg00);
        t01localstate  (debug, ' -transstate', mdMessHead_kb09.mhTrans_kb09.tcdState_gg00);
        t01addr        (debug, ' -next      ', mdNext_kb09);
        CASE mdCommState_kb09 OF
            csFree_ekb09 :
                t01name (debug, ' -cs_free         ');
            csReplyLocalChild_ekb09 :
                t01name (debug, ' -cs_reply_child  ');
            csReqLocalChild_ekb09 :
                t01name (debug, ' -cs_req_child    ');
            csLocalExecution_ekb09 :
                t01name (debug, ' -cs_local_execute');
            OTHERWISE
                t01int4 (debug, ' -comm_state', ord (mdCommState_kb09))
            END;
        (*ENDCASE*) 
        IF  WithMbuf
        THEN
            t01mblock_header (kb_net, ' -md_msshead',
                  mdMessHead_kb09.mhMblock_kb09,
                  mdMessHead_kb09.mhTrans_kb09, NIL);
        (*ENDIF*) 
        t01addr_1 (debug, ' -md_mesbody', mdMessBody_kb09);
        IF  (mdMessBody_kb09 <> NIL) AND WithMbuf
        THEN
            WITH mdMessBody_kb09^ DO
                BEGIN
                t01p2int4 (debug, ' -mby_buflen', mbyBufLen_kb09
                      ,           ' -mby_bufsiz', mbyBufSize_kb09);
                t01addr_1 (debug, ' -mby_next  ', mbyNext_kb09)
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
&endif
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
