/*
 * nexus_resource.h  
 *
 * rcsid = "$Header: /home/globdev/CVS/globus-packages/nexus/source/nexus/nexus_resource.h,v 1.5 2000/01/06 19:26:08 bresnaha Exp $"
 *
 * Resource Abstractions for NEXUS
 *
 */

#ifndef _NEXUS_INCLUDE_NEXUS_RESOURCE_H
#define _NEXUS_INCLUDE_NEXUS_RESOURCE_H


#ifndef EXTERN_C_BEGIN
#    ifdef __cplusplus
#        define EXTERN_C_BEGIN extern "C" {
#        define EXTERN_C_END }
#    else
#        define EXTERN_C_BEGIN
#        define EXTERN_C_END
#    endif
#endif

EXTERN_C_BEGIN


#include <netinet/in.h>

/*
 * the following '#ifndef' allows you to build code with a non qos
 * nexus so you can use the data structures in non-instrumented
 * programs
 */

#ifndef BUILD_RESOURCE

typedef enum {
#define NEXUS_RESOURCE_NTYPES	4
        RESOURCE_SOCKET = 0,
        RESOURCE_PROCESS = 1,
        RESOURCE_THREAD = 2,
        RESOURCE_MEMORY = 3
} nexus_resource_type;

typedef struct _nexus_resource_name_t {
	int				id; 
	nexus_resource_type		type;
} nexus_resource_name_t;

#define nexus_resource_macro_sizeof_name(Count) \
	(Count * nexus_sizeof_int(2))

typedef enum {
#define NEXUS_RUSAGE_N_OPS   3
        RUSAGE_CREATE,
        RUSAGE_DESTROY,
        RUSAGE_MODIFY
} nexus_rusage_op;

typedef struct _nexus_rusage_obj {
	nexus_resource_name_t*		who;
        nexus_rusage_op 		op;
} nexus_rusage_obj;

#endif  /* BUILD_RESOURCE */

/* SOCKET */

typedef enum {
#define NEXUS_RESOURCE_SOCKET_NMODES	4
        RESOURCE_SOCKET_READ,
        RESOURCE_SOCKET_WRITE,
        RESOURCE_SOCKET_RDWR,
        RESOURCE_SOCKET_LISTEN
} nexus_rusage_socket_mode;


typedef struct {
        const nexus_resource_name_t	*who;
        nexus_rusage_op 		op;
        int 				pid;
        int 				fd;
	int 				mode;
        struct sockaddr_in 		addr;
        int 				protocol;
} nexus_rusage_socket;


/* PROCESS */

typedef struct {
        const nexus_resource_name_t	*who;
        nexus_rusage_op 		op;
        int 				pid;
} nexus_rusage_process;


/* THREAD */

typedef struct {
        const nexus_resource_name_t 	*who;
        nexus_rusage_op 		op;
        int 				pid;
  /* An int tid is sufficient for Solaris and IRIX pthreads but not
   * for DCE/pthreads.  In general, a tid may be an arbitrary data
   * type.  This will work for now.
   */
        int 				tid;
} nexus_rusage_thread;


/* MEMORY */

typedef unsigned long nexus_rusage_memory_t;

typedef struct {
        const nexus_resource_name_t	*who;
        nexus_rusage_op 		op;
        nexus_rusage_memory_t 		*handle;
} nexus_rusage_memory;


typedef union {
	nexus_rusage_obj	object;
	nexus_rusage_socket	socket;
	nexus_rusage_process	process;
	nexus_rusage_thread	thread;
	nexus_rusage_memory	memory;
} nexus_rusage_info;


/* name functions */

extern int nexus_resource_name(nexus_resource_name_t*, nexus_resource_type);
extern int nexus_resource_name_cmp(const nexus_resource_name_t*, 
				   const nexus_resource_name_t*); 
extern int nexus_resource_name_cp( nexus_resource_name_t*, 
				   const nexus_resource_name_t* ); 


/* name access functions */

extern nexus_resource_name_t *
nexus_context_name( void );

extern nexus_resource_name_t *
nexus_thread_name( void );

extern nexus_resource_name_t *
nexus_memory_name( void );

extern nexus_resource_name_t *
nexus_socket_name_sp( nexus_startpoint_t * );

extern nexus_resource_name_t *
nexus_socket_name_ep(   nexus_proto_type_t proto_type,  nexus_endpoint_t * );


/* name packing functions */

#ifndef USE_MACROS
extern int nexus_resource_sizeof_name(int count);
#else
#define nexus_resource_sizeof_name(count) \
	nexus_resource_macro_sizeof_name(count)
#endif

extern void nexus_resource_name_put(nexus_buffer_t*, nexus_resource_name_t*);
extern void nexus_resource_name_get(nexus_buffer_t*, nexus_resource_name_t*);


/* rusage packing functions */

extern int nexus_sizeof_rusage(nexus_rusage_obj*, int);
extern void nexus_rusage_put(nexus_buffer_t*, nexus_rusage_obj*);
extern void nexus_rusage_get(nexus_buffer_t*, nexus_rusage_obj*);

EXTERN_C_END

#endif /* _NEXUS_INCLUDE_NEXUS_RESOURCE_H */

