/* rovm.h - ROVM Server 의 중심 헤더 파일.
   Copyright (C) 2006 Weongyo Jeong (weongyo@gmail.com)

This file is part of ROVM.

ROVM 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, or (at your option) any later
version.

ROVM 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 GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#ifndef _ROVM_H
#define _ROVM_H

/** ROVM 의 기본 listening port 번호.  */
#define DEFAULT_ROVM_LISTENING_PORT     4390
/** 사용되지 않는 Ticket 에 대한 만료 시간에 설정 부분입니다.  현재 값으로는 5 분으로
    설정되어 있습니다.  */
#define DEFAULT_TICKET_EXPIRE_TIME      (5 * 60)
/** GC 가 실행되는 주기.  현재 60 초마다 한반씩 실행이 되도록 구성되어 있습니다.
    ??? 이 값도 ROVM 설정 파일에 들어가는 것이 좋을까요?  */
#define DEFAULT_GC_SLEEP_TIME           (1 * 60)

/** 확장자에 대한 문자열.  */
#define DEFAULT_ENVLANG_EXTENSION               ".e"
/** 확장 모듈에 대한 문자열.  */
#define DEFAULT_ENVLANG_NATIVE_EXTENSION        ".so"

typedef struct ggc_globals      rc_gc_t;
typedef struct rc_pod_t         rc_pod_t;
/**
   ROVM 에서 사용하는 opcode 배열에 대한 타입입니다.
 */
typedef unsigned char           rc_opcode_t;

#ifndef MAX_STRING_LEN
/** 만약 MAX_STRING_LEN 가 정의되어 있지 않을 경우, 이를 정의한다.  */
#define MAX_STRING_LEN		1024 * 8
#endif

/**
   ROVM 에 선언된 함수가 wrapper 함수일 경우, 이 매크로를 붙인다.  단순히
   가독성을 높이기 위한 조치이다.  그리고 깨끗하게 정리할 수 있도록 하기 
   위해서 이다.
 */
#define RC_WRAPPER_FUNC

/*
   ROVM Reserved Commands.
 */
#include "command.def"

/**
   ROVM 서버에서 발급하는 ticket 의 기본 크기를 가르킨다.  
*/
#define TICKETID_SIZE	ROVM_SHA1_DIGESTSIZE

#define PROCREC_POOL(NODE)		((NODE)->pool)
#define PROCREC_PCONF(NODE)		((NODE)->pconf)
#define PROCREC_ARGC(NODE)		((NODE)->argc)
#define PROCREC_ARGV(NODE)		((NODE)->argv)
#define PROCREC_NAME(NODE)		((NODE)->short_name)

/**
   하나의 프로세스를 나타내는 구조체.
*/
struct process_rec
{
  /** Global pool. 정상적인 exit 시 삭제된다.  */
  rc_pool_t *pool;
  /** 설정 관련 pool.  재시작시 깨끗히 삭제된다.  */
  rc_pool_t *pconf;
  /** 프로그램에 전달된 Command 라인 argument 의 숫자.  */
  int argc;
  /** Command 라인 argument 들.  */
  const char * const *argv;
  /** 프로그램을 실행되는데, 사용된 프로그램 이름.  */
  const char *short_name;
};

#define CONF_ONE_PROCESS(NODE)          ((NODE)->one_process)
#define CONF_NO_DETACH(NODE)            ((NODE)->no_detach)
#define CONF_DAEMONS_TO_START(NODE)     ((NODE)->daemons_to_start)
#define CONF_DAEMONS_LIMIT(NODE)        ((NODE)->daemons_limit)
#define CONF_MAX_DAEMONS_LIMIT(NODE)    ((NODE)->max_daemons_limit)
#define CONF_SEND_BUFFER_SIZE(NODE)     ((NODE)->send_buffer_size)
#define CONF_RECEIVE_BUFFER_SIZE(NODE)  ((NODE)->receive_buffer_size)
#define CONF_LISTENBACKLOG(NODE)        ((NODE)->listenbacklog)
#define CONF_PORT(NODE)                 ((NODE)->port)
#define CONF_THREADS_PER_CHILD(NODE)	((NODE)->threads_per_child)
#define CONF_ERROR_LOG(NODE)            ((NODE)->errlog)
#define CONF_LOGLEVEL(NODE)             ((NODE)->loglevel)
#define CONF_OPTION(NODE)               ((NODE)->bit_option)
#define CONF_DEFAULT_STACK_SLOT(NODE)   ((NODE)->default_stack_slot)
#define CONF_CLASSROOT(NODE)            ((NODE)->classroot)

#define OPTION_LOG_DEBUG_MESSAGES       (1 << 1)

/**
   ROVM 설정 구조체.
 */
struct rovm_config
{
  /** 오직 하나의 프로세스만 원할 경우, 이 값을 1 로 설정한다. 그렇지 않다면 0 으로
      설정한다.  */
  int one_process;
  int no_detach;

  int daemons_to_start;
  int daemons_limit;
  int max_daemons_limit;

  /* Listen 관련 변수들.  */
  int send_buffer_size;
  int receive_buffer_size;
  int listenbacklog;

  /** Listening 을 할 포트 번호를 지정한다.  */
  rc_port_t port;

  /** Child 당 생성할 thread 수를 결정한다.  */
  int threads_per_child;

  /** Debug 메세지를 남길 파일에 대한 포인터.  */
  FILE *errlog;
  /** 기본 debug 레벨.  이 값에 따라서 남길 로그의 레벨이 결정됩니다.  */
  int loglevel;

  /** ROVM 프로그램의 옵션을 설정하는 변수로써, 로그 기록 유무 등등을 설정할 수
      있습니다.  */
  int bit_option;

  /** Ticket 이 생성될 때, 기본적으로 생성될 스택 slot 갯수를 정합니다.  */
  int default_stack_slot;

  /** Class 파일들이 존재하는 디렉토리의 root 경로.  */
  char *classroot;
};

#define STATUS_SHUTDOWN_PENDING(NODE)   ((NODE)->shutdown_pending)
#define STATUS_RESTART_PENDING(NODE)    ((NODE)->restart_pending)

struct rovm_status
{
  int shutdown_pending;
  int restart_pending;
};

struct process_score
{
  pid_t pid;  
};

#define SB_PARENT(NODE)                 ((NODE)->parent)
#define SB_PARENT_IDX(NODE, IDX)        (&((NODE)->parent[(IDX)]))

struct rovm_scoreboard
{
  struct process_score *parent;
};

#define ROVM_POOL(NODE)                 PROCREC_POOL (ROVM_PROCESS (NODE))
#define ROVM_CONF(NODE)			((NODE)->config)
#define ROVM_STATUS(NODE)               ((NODE)->status)
#define ROVM_PROCESS(NODE)		((NODE)->process)
#define ROVM_POD(NODE)                  ((NODE)->pod)
#define ROVM_LISTENERS(NODE)            ((NODE)->listeners)
#define ROVM_TKTREE(NODE)		((NODE)->tk)
#define ROVM_TKMUTEX(NODE)              ((NODE)->tkmutex)
#define ROVM_CLSTREE(NODE)              ((NODE)->cls)
#define ROVM_MUTEX(NODE)                ((NODE)->mutex)
#define ROVM_GC(NODE)                   ((NODE)->gc)
#define ROVM_GC_MUTEX(NODE)             ((NODE)->gc_mutex)
#define ROVM_SCOREBOARD(NODE)           ((NODE)->sb)

/**
   ROVM 의 전체 구조체.
 */
struct rovm
{
  /** ROVM 의 설정 구조체이다.  여러 세부 설정 정보를 가지고 있다.  */
  struct rovm_config *config;
  /** ROVM Server 의 상태에 대해서 기록하는 구조체.  */
  struct rovm_status *status;

  /** 현재 실행된 프로세스의 정보를 가지고 있다.  */
  struct process_rec *process;

  /** ROVM 의 경우, 구조상으로 다수의 listening port 를 처리할 수 있도록
      설계되어 있지만, 현재는 하나의 port 만 사용하므로 listeners 의 next 는
      NULL 값일 것이다.  하지만 다수의 port 를 사용하도록 수정할 수 있다.  */
  rc_listen_rec *listeners;

  /** Pipe-of-Death 를 위한 변수.  */
  rc_pod_t *pod;
  struct rovm_scoreboard *sb;

  /** ROVM Server 에서 일반적으로 사용되는 mutex.  */
  rc_thread_mutex_t *mutex;

  /** 전체 Ticket 을 관리하는 tree 구조체.  Key 와 Value 쌍으로 구성되어 있다.  */
  tktree_t *tk;
  /** Ticket 을 위한 mutex.  */
  rc_thread_mutex_t *tkmutex;

  /** 전체 Class 를 관리하는 tree 구조체.  */
  clstree_t *cls;

  /** Garbage Collector 정보를 가지는 구조체.  */
  rc_gc_t *gc;
  /** Garbage Collector 를 위해서만 사용되는 mutex.  */
  rc_thread_mutex_t *gc_mutex;
};

#endif
