/*
* Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2.1 of the GNU Lesser General Public
* License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
* USA.
*
* Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
* Mountain View, CA 94043, or:
*
* http://www.sgi.com
*
* For further information regarding this notice, see:
*
* http://oss.sgi.com/projects/GenInfo/NoticeExplan
*/
/*
* ci_ipc.h
*
* Header file for IPC library
*
*/
#ifndef CI_IPC_H
#define CI_IPC_H
#ident "$Id: ci_ipc.h,v 1.1 2000/08/31 19:16:32 vasa Exp $"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/times.h>
#include <ci_clock.h>
#include <ci_log.h>
#include <ci_misc.h>
#define CI_IPC_MSG_SIZE (8 * 1024) /* 8k messages max */
#define CI_IPC_MAX_FILENAME MAXPATHLEN
#define CI_IPC_INITIAL_HB_INTERVAL 100000 /* 100 secs default */
#define CI_IPC_BIG_HB_INTERVAL 0xf0000000 /* Used by client who
* do not want to
* pulse server */
#define CI_IPC_NOSIG 0
#define CI_IPC_BLOCK 0x1
#define CI_IPC_NON_BLOCK 0x2
#define CI_IPC_PULSE 0x4
#define CI_IPC_NON_PULSE 0x8
typedef struct pulse_info_s {
ci_clock_t heartbeat_interval;
ci_clock_t next_heartbeat_time;
uint64_t client_value;
uint64_t server_value;
int32_t pulse_on;
} pulse_info_t;
/* data structure for passing in msg_hdr and msg_body from */
/* gcs to ipc and back during gcs_send/gcs_recv. */
typedef struct msg_desc {
uint32_t msg_len;
char * msg_ptr;
} msg_desc_t;
typedef struct ci_ipc_clnt_s* ipcclnt_hdl_t;
typedef struct ci_ipc_cca_s* ipcserv_hdl_t;
typedef struct ci_ipc_connect_req_s* ipcserv_connhdl_t;
typedef struct ci_ipc_dirent_s {
int32_t offset;
int32_t length;
} ci_ipc_dirent_t;
typedef enum {
EMPTY,
FULL,
OK
} dir_flag_t;
typedef struct ci_ipc_comm_area_s {
dir_flag_t flag;
uint32_t write_ptr;
uint32_t read_ptr;
uint32_t free_mem;
uint32_t num_msgs;
uint32_t messages_offset;
} ci_ipc_comm_area_t;
typedef enum {
CI_IPC_CONNECT_VALID,
CI_IPC_CONNECT_INVALID,
CI_IPC_CONNECT_COMPLETE,
CI_IPC_CONNECT_ERROR
} ci_ipc_connect_status_t;
typedef struct ci_ipc_connect_req_s {
pid_t server_pid;
int server_conn_fd;
/* name of server connection file */
char server_conn_file[CI_IPC_MAX_FILENAME];
/* name of client specified communication file. given by the client. */
char mmap_file[CI_IPC_MAX_FILENAME];
int32_t mmap_length;
/* a client may send me this signal to make me accept a connection */
uint32_t accept_sig;
ci_ipc_connect_status_t connect_status;
/* VALID|INVALID|COMPLETE|ERROR */
ci_err_t error;
uint32_t connect_count;
} ci_ipc_connect_req_t;
typedef enum {
CI_IPC_CCA_NOCONNECTION,
CI_IPC_CCA_CONNECTED,
CI_IPC_CCA_OKTOCLOSE
} ci_ipc_cca_status_t;
typedef struct ci_ipc_cca_s {
ci_ipc_cca_status_t cca_status;
/* NOCONNECTION|CONNECTED */
int32_t serv_mmapfd;
ci_err_t error;
int32_t cca_size;
boolean_t mpin_cca;
int32_t client_sig;
int32_t server_sig;
pid_t client_pid;
pid_t server_pid;
pulse_info_t client_pulse_info;
pulse_info_t server_pulse_info;
ci_ipc_comm_area_t recv_commarea;
ci_ipc_comm_area_t send_commarea;
} ci_ipc_cca_t;
typedef struct ci_ipc_clnt_s {
ci_ipc_cca_t* ccap;
char mmap_file[CI_IPC_MAX_FILENAME];
int mmap_fd;
int32_t mmap_length;
boolean_t mpin_cca;
pid_t client_pid;
pid_t server_pid;
int ipc_flag;
} ci_ipc_clnt_t;
/* Connection status in connect_req */
#define VALID 0x1
#define INVALID 0x2
#define COMPLETE 0x4
#define ERROR 0x8
/* Communication status in cca_status */
#define NOCONNECTION 0x0
#define CONNECTED 0x1
/* IPC client function prototypes */
ci_err_t ipcclnt_create(ipcclnt_hdl_t *, uint32_t, boolean_t, ci_clock_t);
ci_err_t ipcclnt_connect(ipcclnt_hdl_t, char *, char *, uint32_t );
ci_err_t ipcclnt_destroy(ipcclnt_hdl_t);
ci_err_t ipcclnt_send(ipcclnt_hdl_t, int, msg_desc_t *);
ci_err_t ipcclnt_recv(ipcclnt_hdl_t, int, msg_desc_t *);
ci_err_t ipcclnt_recvcheck(ipcclnt_hdl_t, char *, uint32_t *);
ci_err_t ipcclnt_pulse(ipcclnt_hdl_t, ci_clock_t);
ci_err_t ipcclnt_changepid(ipcclnt_hdl_t, pid_t);
boolean_t ipcclnt_can_send(ipcclnt_hdl_t, uint32_t);
pid_t ipcclnt_getserverpid(ipcclnt_hdl_t client);
ci_err_t ipcclnt_ctl(ipcclnt_hdl_t client, int32_t request);
uint32_t ipcclnt_maxmsg_size(ipcclnt_hdl_t);
/* IPC server function prototypes */
ci_err_t ipcserv_init(ipcserv_connhdl_t *, char *, uint32_t );
ci_err_t ipcserv_destroy(ipcserv_connhdl_t);
ci_err_t ipcserv_accept(ipcserv_hdl_t *, ipcserv_connhdl_t, uint32_t,
boolean_t, ci_clock_t);
ci_err_t ipcserv_close(ipcserv_hdl_t);
ci_err_t ipcserv_oktoclose(ipcserv_hdl_t);
ci_err_t ipcserv_send(ipcserv_hdl_t, char *, uint32_t);
ci_err_t ipcserv_recv(ipcserv_hdl_t, char *, uint32_t *);
ci_err_t ipcserv_recvcheck(ipcserv_hdl_t, char *, uint32_t *);
ci_err_t ipcserv_pulse(ipcserv_hdl_t, ci_clock_t);
ci_err_t ipcserv_changepid(ipcserv_hdl_t, pid_t);
boolean_t ipcserv_can_send(ipcserv_hdl_t, uint32_t);
pid_t ipcserv_getclientpid(ipcserv_hdl_t ccap);
uint32_t ipcserv_maxmsg_size(ipcserv_hdl_t);
int32_t gmc_nap(int32_t);
#endif