/*
 ******************************************************************************
 *  Copyright 1997 DeltaLink bv. All Rights Reserved.
 ******************************************************************************
 *
 * DeltaLink Intertask Mailbox Communication IMX
 *
 * File         :   imx_mt.h
 *
 * Version      :   1.00
 *
 * Developed by :   Leon Westervoort.
 *
 * This file contains data- and prototypes of the DeltaLink Mailbox
 * Communication Interface Multi-Threading extensions.
 *
 */
#ifndef _IMX_MT_DEFS_INCLUDED /* { */
#define _IMX_MT_DEFS_INCLUDED 1

#ifndef HPUX
/*pragma pack(1)*/
#else
#pragma HP_ALIGN HPUX_WORD PUSH
#endif

/* define the types for every platform */

#ifdef WIN32

typedef HANDLE PIPE;
typedef HANDLE SEM;
typedef unsigned long T_ID;

#endif

#ifdef SCO

typedef int PIPE;
typedef int SEM;
typedef pid_t T_ID;

#endif

#ifdef UNIX

typedef int PIPE;
typedef int SEM;
typedef pthread_t T_ID;

#endif

/* define the maximum size of the buffer for reading the mailbox of the task */

#define  MT_MBX_BUF_SIZE   (8192 + sizeof( IMXDS))

#define  MT_EXIT_TIMEOUT   (20 * 1000)

#define  IMX_MT_DEC_MAX    2500
/*
 *
 */
#define  IMX_MT_READ      0
#define  IMX_MT_WRITE    1
#define  IMX_MT_RCV      2

/*
 * multi-threading extension error codes
 */
#define MTE_NOMEMORY  70      /* no memory left */
#define MTE_REGISTER  71      /* error registering standard dataset */
#define MTE_WRITE     72      /* error writing message in pipe */
#define MTE_COMMAND   73      /* not supported IMX message */
#define MTE_CREATE    74      /* error creating pipe */
#define MTE_THREAD    75      /* error starting threat */
#define MTE_SCONNECT  76      /* error server connecting to pipe */
#define MTE_CCONNECT  77      /* error child connecting to pipe */
#define MTE_RPIPE     78      /* error reading the pipe */
#define MTE_NREAD     79      /* error number of bytes read */
#define MTE_WPIPE     80      /* error writing the pipe */
#define MTE_NWRITE    81      /* error number of bytes written */
#define MTE_IMX_RECV  82      /* error reading dataset from the mailbox */
#define MTE_BUFFER    83      /* no communication buffers assigned */
#define MTE_DECR_SEM  84      /* error decrementing semaphore */
#define MTE_PIPE_FULL 85      /* error writing to pipe, no space left */
#define MTE_QRY_DEC   86      /* error querying no. of messages for decoder */
#define MTE_MAX_MSG   87      /* max. messages in decoder mbx reached */

/*
 * Definition of a IMX device. This device contains three processes, for reading,
 * writing and receiving. The read and the write process have a pipe attached.
 */
typedef struct _imx_device {

  char  name[ MAX_TAG_NAME + MAX_DIM_LENGTH +16];    /* name of the imx device */

  MSG   buffer[ 3];         /* communication buffers */

  T_ID  t_id[ 3];           /* handle of the read, write and receive thread */
  PIPE  spipe[ 2];          /* pipes for read and write of the parent process */
  PIPE  cpipe[ 2];          /* pipes for read and write of the child process */
  ulong *free[ 2];          /* free space in pipe */
  ulong space[ 2];          /* free space in pipe */

  int   (*thread[3])( struct _imx_device *, int);  

  void  *dev_info;          /* pointer to additional device information */

} IMX_DEVICE;


/*
 * Definition of a multi-threaded dataset object which contains the normal IMX
 * dataset object with the pipe information
 */
typedef struct _mt_imxds {

  IMXDS             ds;           /* copy of the registed dataset in the IMX library */
  IMXDS             *reg_ds;      /* the registed dataset in the IMX library */

  IMX_DEVICE        *device;      /* pointer to device with thread info */

  void              *u_data;      /* pointer to the user attached information */

  int               reading;      /* flag indicating that this dataset is currently being read */

  struct _mt_imxds  *org;         /* pointer to original mt dataset */

} MT_IMXDS;


/* variable indicating if the thread has to stop or not */

extern int Stop;

/* variable used for defining pipe buffer size */

#ifdef NT
extern int Pipe_Size;
#endif

/* 
 * function definition of the multi-threaded extension
 */
int Imx_MT_Init               ( IMXSYSTEM *);
int Imx_MT_Exit               ( void);

int Imx_MT_CreateThread       ( IMX_DEVICE *);
int Imx_MT_CreateSem          ( void);
int Imx_MT_Wait_SemExit       ( void);
int Imx_MT_Thread_Exit        ( IMX_DEVICE *, int);
int Imx_MT_Wait               ( IMX_DEVICE *, int, IMXDS **);
int Imx_MT_Write              ( MT_IMXDS *, int);

IMXDS *Imx_MT_Ds_Register     ( IMXDS *, IMX_DEVICE *);
int Imx_MT_Event              ( IMXDS *);

#ifdef NT 
int Imx_MT_Thread_Read_Init   ( IMX_DEVICE *);
int Imx_MT_Thread_Write_Init  ( IMX_DEVICE *);
int Imx_MT_Thread_Rcv_Init    ( IMX_DEVICE *);
#endif

#ifdef UNIX 
void * Imx_MT_Thread_Read_Init   ( void *);
void * Imx_MT_Thread_Write_Init  ( void *);
void * Imx_MT_Thread_Rcv_Init    ( void *);
#endif

#define Imx_MT_Set_Name( d, n)          strcpy( (d)->name, (n))
#define Imx_MT_Get_Name( d)             (d)->name

#define Imx_MT_Set_Thread(  d, i, f)    ((d)->thread[ (i)] = (f))
#define Imx_MT_Get_Thread(  d, i)       (d)->thread[ (i)]

#define Imx_MT_Set_Buffer( d, b, f)     memcpy( &(d)->buffer[ (f)], (b), sizeof( MSG))
#define Imx_MT_Get_Buffer( d, f)        &(d)->buffer[ (f)]

#define Imx_MT_Set_DevInfo( d, p)       ((d)->dev_info = (p))
#define Imx_MT_Get_DevInfo( d)          (d)->dev_info


#define Imx_MT_Get_Stop()               Stop
#define Imx_MT_Set_Stop()               ( Stop = 1 )

#ifdef NT
#define Imx_MT_Set_Pipe_Size( n)        ( Pipe_Size = n )
#define Imx_MT_Set_Pipe_Error( n)       ( Pipe_Error = n )
#endif

#ifndef HPUX
/*pragma pack()*/
#else
#pragma HP_ALIGN POP
#endif

#endif /* _IMX_MT_DEFS_INCLUDED */
