/*
   "ipc.h" - part of "RAGMAAN, een anagrammengenerator"

   This module contains all the SYS V IPC stuff:

     shared memory, semaphores, signal handlers, 
     creation of the server process

   Copyright (C) 1999 Raymond Zandbergen

   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., 675 Mass Ave, Cambridge, MA 02139, USA.

   The maintainer of this program is Raymond Zandbergen (ray@wirehub.nl)
 */

#ifndef	IPC_H
#define	IPC_H

#include <unistd.h>
#include "server_commands.h"

#define	OK		(0)
#define	ERROR		(-1)

/*** 	semaphores	***/

#define	NOF_SEMAPHORES	(5)

#define	LOCK_SHM	(1)
#define	NEW_CMD		(2)
#define	CMD_ACK		(3)
#define	SERVER_INIT	(4)

/***	parameter to read_command ***/

#define	BLOCKING	(1)
#define	NONBLOCKING	(2)

#define	SIGNATURE_LENGTH	(40)

struct async_data_s
  {
    int server_working;
  };

struct SHM_POOL_S

/*
 * shared memory layout, used by both client (frontend) and server
 */

  {

    char signature[SIGNATURE_LENGTH];
    CMD_T cmd;
    REPLY_T reply;
    int server_running;
    int progress;
    int shm_id;
    int sem_id;
    pid_t client_pid;
    pid_t server_pid;
    struct async_data_s async_data;

  };

typedef struct SHM_POOL_S SHM_POOL_T;

extern SHM_POOL_T *shm;

extern void sem_down_id (int sem_id, int sem_num);
extern int tsem_down_id (int sem_id, int sem_num, int sec, int usec);

extern void sem_up_id (int sem_id, int sem_num);
extern void sem_set_id (int sem_id, int sem_num, int sem_val);

extern int sem_create (int nof_semaphores);
extern void sem_remove (int sem_id);

#define	sem_down(sem_num)	sem_down_id(shm->sem_id, sem_num)

/* ssem_down returns -1 if interrupted by a signal, 0 otherwise */

#define	ssem_down(sem_num)	ssem_down_id(shm->sem_id, sem_num)

/* tsem_down returns -1 after a timeout, 0 otherwise */

#define	tsem_down(sem_num, sec, usec)	\
				tsem_down_id(shm->sem_id, sem_num, sec, usec)
#define	sem_up(sem_num)		sem_up_id(shm->sem_id, sem_num)
#define	sem_set(sem_num,sem_val) sem_set_id(shm->sem_id, sem_num, sem_val)

#define	shm_lock()	sem_down(LOCK_SHM)
#define	shm_unlock()	sem_up(LOCK_SHM)

extern int shm_get (void);
extern SHM_POOL_T *shm_attach (int shm_id);
extern void shm_detach (SHM_POOL_T * shm);
extern void shm_remove (int shm_id);

extern int read_command (int block_flag);
extern int tread_command (int sec, int usec);
#define	write_reply()	sem_set(CMD_ACK,1)

extern void server_command (int *progress);

extern pid_t server_create (char *file_name,
			  CMD_T ** server_command, REPLY_T ** server_reply);
extern void server_destroy (void);
extern void sigusr1_handler (int dummy);
extern void sigchld_handler (int dummy);
extern void die (int signal);
extern void report_progress (int progress);
extern void cleanup (void);

#endif
