/*!
  @file           vos62k.c
  @author         RaymondR
  @brief          vcreate/vkill
  @see            

\if EMIT_LICENCE
    ========== licence begin  GPL
    Copyright (c) 2001-2005 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

\endif
*/




/*
 * INCLUDE FILES
 */
#include "gos00.h"
#include "heo00.h"
#include "heo46.h"
#include "geo007_1.h"
#include "gos00k.h"
#include "geo002.h"


/*
 *  DEFINES
 */
#define MOD__  "VOS62KC : "
#define MF__   MOD__"UNDEFINED"

/*
 *  MACROS
 */


/*
 *  LOCAL TYPE AND STRUCT DEFINITIONS
 */


/*
 * EXTERNAL VARIABLES
 */


/*
 *  EXPORTED VARIABLES
 */


/*
 * LOCAL VARIABLES
 */


/*
 * LOCAL FUNCTION PROTOTYPES
 */
static VOID sql62k_start_server_task ( PTASK_CTRL_REC  pServTaskCtrl );
static VOID sql62k_kill_server_task  ( PUKT_CTRL_REC   pUKT,
                                       PTASK_CTRL_REC  pServTaskCtrl );

/*
 * ========================== GLOBAL FUNCTIONS ================================
 */

VOID vcreate ( tsp2_process_type  proc_type,
               PROCESS_ID        *pid,
               BOOLEAN           *ok )
  {
  #undef  MF__
  #define MF__ MOD__"vcreate"
  PUKT_CTRL_REC         pUKT         = THIS_UKT_CTRL;
  PTASK_CTRL_REC        pServTaskCtrl;

  DBGIN;

  pUKT->pCTask->TaskState = TSK_VCREATE;
  *ok = FALSE;

  if ( XPARAM(fDynamicServerTasks) )
    {
    if ( proc_type == sp2pt_server )
      {
      for (pServTaskCtrl  = kgs.pFirstServerTaskCtrl;
           pServTaskCtrl <= kgs.pLastServerTaskCtrl;
           pServTaskCtrl++)
        {
        if ( pServTaskCtrl->TaskState != TSK_INACTIVE ) continue;

        WAIT_UNTIL_ALONE( &pServTaskCtrl->pUKT->lExclusive );

        if ( pServTaskCtrl->TaskState == TSK_INACTIVE )
          {
          pServTaskCtrl->TaskState = TSK_MARKED_FOR_STARTUP;
          CLEARLOCK( &pServTaskCtrl->pUKT->lExclusive );
          break;
          }
        CLEARLOCK( &pServTaskCtrl->pUKT->lExclusive );
        }

      if ( pServTaskCtrl <= kgs.pLastServerTaskCtrl )
        {
        if ( sql88k_create_task_or_fiber ( pServTaskCtrl ) == NO_ERROR )
          {
          sql62k_start_server_task ( pServTaskCtrl );

          *ok  = TRUE;
          *pid = pServTaskCtrl->ulTaskIndex + 1;
          }
        else
          pServTaskCtrl->TaskState = TSK_INACTIVE;
        }
      else
        {
        MSGD (( ERR_NO_FREE_SERVER_TASK ));
        DBG1 (( MF__, "Not enough server tasks" ));
        }
      }
    else
      {
      *ok = FALSE;
      MSGD (( ERR_WRONG_TASK_TYPE, proc_type ));
      DBG1 (( MF__, "Wrong task type: %d", proc_type));
      }
    }

  pUKT->pCTask->TaskState = TSK_RUNNING;

  DBGOUT;
  return;
  }

/*------------------------------*/

VOID vkill ( PROCESS_ID    pid )
  {
  #undef  MF__
  #define MF__ MOD__"vkill"
  PUKT_CTRL_REC         pUKT         = THIS_UKT_CTRL;
  PTASK_CTRL_REC        pServTaskCtrl;

  DBGIN;

  pUKT->pCTask->TaskState = TSK_VKILL;

  if ( XPARAM(fDynamicServerTasks) )
    {
    for (pServTaskCtrl  = kgs.pFirstServerTaskCtrl;
         pServTaskCtrl <= kgs.pLastServerTaskCtrl &&
         (ULONG)pid    != pServTaskCtrl->ulTaskIndex;
         pServTaskCtrl++)  {;}

    if ( pServTaskCtrl <= kgs.pLastServerTaskCtrl )
      {
      if (( pServTaskCtrl->TaskState != TSK_INACTIVE    ) &&
          ( pServTaskCtrl->TaskState != TSK_INITIALIZED ) &&
          ( pServTaskCtrl->TaskState != TSK_MARKED_FOR_STARTUP ))
        {
        sql62k_kill_server_task ( pUKT, pServTaskCtrl );
        }
      else
        {
        MSGD (( ERR_TASK_NOT_ACTIVE, pid ));
        DBG1 (( MF__, "Requested task %d not active", pid ));
        }
      }
    else
      {
      MSGD (( ERR_VXXXX_WRONG_TASK, "vkill", pid ));
      DBG1 (( MF__, "Wrong pid %u", pid ));
      }
    }

  pUKT->pCTask->TaskState = TSK_RUNNING;

  DBGOUT;
  return;
  }


/*
 * ========================== LOCAL FUNCTIONS =================================
 */

static VOID sql62k_start_server_task ( PTASK_CTRL_REC pServTaskCtrl )
  {
  #undef  MF__
  #define MF__ MOD__"sql62k_start_server_task"
  PDLQ_REC              pRequest;

  DBGIN;

  pRequest                 = RESERVE_FREELIST_ELEM();
  pRequest->ulReqType      = REQ_INITOK;
  sql73k_UKT_enqu ( pServTaskCtrl->pUKT, pServTaskCtrl, pRequest );

  DBGOUT;
  return;
  }

/*------------------------------*/

static VOID sql62k_kill_server_task ( PUKT_CTRL_REC   pUKT,
                                      PTASK_CTRL_REC  pServTaskCtrl )
  {
  #undef  MF__
  #define MF__ MOD__"sql62k_kill_server_task"
  PDLQ_REC              pRequest;

  DBGIN;

  if (( pServTaskCtrl->pUKT == pUKT ) && ( pUKT->pCTask == pServTaskCtrl ))
    {
    // --- it's me !

    sql51k_finish ();

    MSGD (( ERR_TASK_RETURNED ));   // --- we should never return here
    ABORT();
    }
  else
    {
    pRequest                 = RESERVE_FREELIST_ELEM();
    pRequest->ulReqType      = REQ_FINISH_SV;
    sql73k_UKT_enqu ( pServTaskCtrl->pUKT, pServTaskCtrl, pRequest );
    }

  DBGOUT;
  return;
  }

/*
 * =============================== END ========================================
 */
