/*
Copyright (c) 1993 Xerox Corporation.  All rights reserved.
*/
/*
$Id$

$Date$
 *
 * PCR - I/O global (per-pcr-world) descriptor support
 *
 * Not for client use.
 */

#ifndef	←←PCR←IOGbl←h
#define ←←PCR←IOGbl←h 1

#include <config/PCR←StdDefs.h>
#include <th/PCR←Th.h>
#include <sys/stat.h>
#include <io/PCR←IO.h>

typedef volatile struct PCR←IOGbl←DERep * PCR←IOGbl←DEPtr;

typedef struct PCR←IOGbl←DEProcsRep * PCR←IOGbl←DEProcsPtr;

/*
 * I/O methods of global descriptor objects
 */

typedef PCR←ERes
PCR←IOGbl←ReadProc(
    PCR←IOGbl←DEPtr gde,
    char *buf, unsigned int nbyte,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←ReadProc PCR←IOGbl←Read;


typedef PCR←ERes
PCR←IOGbl←WriteProc(
    PCR←IOGbl←DEPtr gde,
    char *buf, unsigned int nbyte,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←WriteProc PCR←IOGbl←Write;


typedef PCR←ERes
PCR←IOGbl←LSeekProc(
    PCR←IOGbl←DEPtr gde,
    off←t offset, int whence, off←t *where,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←LSeekProc PCR←IOGbl←LSeek;


typedef PCR←ERes
PCR←IOGbl←FStatProc(
    PCR←IOGbl←DEPtr gde,
    struct PCR←stat *sbuf,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FStatProc PCR←IOGbl←FStat;


typedef PCR←ERes
PCR←IOGbl←FPathConfProc(
    PCR←IOGbl←DEPtr gde,
    int name,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FPathConfProc PCR←IOGbl←FPathConf;


typedef PCR←ERes
PCR←IOGbl←FCntlProc(
    PCR←IOGbl←DEPtr gde,
    int cmd, PCR←Any arg, int *ansp,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FCntlProc PCR←IOGbl←FCntl;


typedef PCR←ERes
PCR←IOGbl←WaitReadyProc(
    PCR←IOGbl←DEPtr gde,
    PCR←IO←WaitReadyEvents events,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←WaitReadyProc PCR←IOGbl←WaitReady;



typedef PCR←ERes
PCR←IOGbl←GenericOpProc(
    PCR←IOGbl←DEPtr gde,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup,
    PCR←Any cmd, ...
);

extern PCR←IOGbl←GenericOpProc *
        (PCR←IOGbl←GetGenericOpProc(PCR←IOGbl←DEPtr));

int PCR←IOGbl←←ctlGenericOpCmd;
#define PCR←IOGbl←ctlGenericOpCmd \
        ((PCR←Any)(&PCR←IOGbl←←ctlGenericOpCmd))

PCR←Bool PCR←IOGbl←doAllIOCtls;



typedef PCR←ERes
PCR←IOGbl←GenericCloneProc(
    PCR←IOGbl←DEPtr gde,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup,
    PCR←IOGbl←DEPtr * gdep,
    PCR←Any cmd, ...
);

extern PCR←IOGbl←GenericCloneProc *
        (PCR←IOGbl←GetGenericCloneProc(PCR←IOGbl←DEPtr));


typedef PCR←ERes
PCR←IOGbl←FSyncProc(
    PCR←IOGbl←DEPtr gde,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FSyncProc PCR←IOGbl←FSync;


typedef PCR←ERes
PCR←IOGbl←FChModProc(
    PCR←IOGbl←DEPtr gde,
    mode←t mode,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FChModProc PCR←IOGbl←FChMod;


typedef PCR←ERes
PCR←IOGbl←FChOwnProc(
    PCR←IOGbl←DEPtr gde,
    uid←t owner,
    gid←t group,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FChOwnProc PCR←IOGbl←FChOwn;



typedef PCR←ERes
PCR←IOGbl←FTruncateProc(
    PCR←IOGbl←DEPtr gde,
    off←t length,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←FTruncateProc PCR←IOGbl←FTruncate;


typedef PCR←ERes
PCR←IOGbl←CloseProc(
    PCR←IOGbl←DEPtr gde,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup
);

extern PCR←IOGbl←CloseProc PCR←IOGbl←Close;


typedef struct PCR←IOGbl←DEProcsRep {
    PCR←IOGbl←ReadProc * gdep←read;
    PCR←IOGbl←WriteProc * gdep←write;
    PCR←IOGbl←LSeekProc * gdep←lSeek;
    PCR←IOGbl←FStatProc * gdep←fStat;
    PCR←IOGbl←FPathConfProc * gdep←fPathConf;
    PCR←IOGbl←FCntlProc * gdep←fCntl;
    PCR←IOGbl←WaitReadyProc * gdep←waitReady;
    PCR←IOGbl←GenericOpProc * gdep←genericOp;
    PCR←IOGbl←GenericCloneProc * gdep←genericClone;
    PCR←IOGbl←FSyncProc * gdep←fSync;
    PCR←IOGbl←FChModProc * gdep←fChMod;
    PCR←IOGbl←FChOwnProc * gdep←fChOwn;
    PCR←IOGbl←FTruncateProc * gdep←fTruncate;
    PCR←IOGbl←CloseProc * gdep←close;
} PCR←IOGbl←DEProcs;


/*
 * global descriptor objects
 */

#define PCR←IOGbl←GDE←NDATA	2

typedef volatile struct PCR←IOGbl←DERep {
    /* procs */
        PCR←IOGbl←DEProcsPtr gde←gdep;
    /* private data used by procs */
        union {
            void * gde←data←←ptr;
            long gde←data←←long;
        } gde←data[PCR←IOGbl←GDE←NDATA];
    /* translation to/from global fildes values */
        PCR←ERes gde←gfd;
    /* ref counts -- global and cumulative (local+global) */
        unsigned gde←gRefCnt;
        unsigned gde←refCnt;
    /* per-descriptor data for fcntl */
        int gde←fcntlFD;
        int gde←fcntlFL;
} PCR←IOGbl←DE;


extern PCR←IOGbl←DEPtr * PCR←IOGbl←gde;


extern PCR←IOGbl←DEPtr
PCR←IOGbl←DEPtr←FromFD(int fildes);

extern PCR←IOGbl←DEPtr
PCR←IOGbl←DEPtr←FromGFD(int fildes);
/*
    Convert a (global) fildes to a DEPtr.
    Result may be NIL (EBADF), or the returned gde
      may have been closed concurrently.
*/

#define PCR←IOGbl←DEPtr←←FromGFD(gfd) \
	PCR←IOGbl←gde[gfd]
#define PCR←IOGbl←DEPtr←FromGFD		PCR←IOGbl←DEPtr←←FromGFD

#define PCR←IOGbl←DEPtr←FromGFDChecked(gfd) \
	( PCR←IO←FDIsValidGlobal(gfd) ? PCR←IOGbl←DEPtr←FromGFD(gfd) : NIL ) 

#define PCR←IOGbl←DEPtr←FromFDChecked(fd) \
	PCR←IOGbl←DEPtr←FromFD(fd)

/*
 * Ref count manipulation, for dup, close etc.
 */

extern PCR←ERes
PCR←IOGbl←DEPtr←AssignGFD(PCR←IOGbl←DEPtr gde, PCR←Bool gbl);
/*
    Assign an unused GFD to gde.
    Initialize ref count.
*/


extern PCR←ERes
PCR←IOGbl←DEPtr←AddRef(PCR←IOGbl←DEPtr gde, PCR←Bool gbl);
/*
    Increment reference count.
    Fails if count is not already positive.
*/


PCR←ERes
PCR←IOGbl←DEPtr←DelRef(
    PCR←IOGbl←DEPtr gde, PCR←Bool gbl,
    const PCR←sigset←t *sigMask, PCR←Msec wakeup );
/*
    Decrement ref count.
    When total ref count reaches 0, release gfd slot and call close proc. 
*/


#define PCR←IOGbl←←Read(gde,buf,nbyte,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←read))(\
		(gde),(buf),(nbyte),(sigMask),(wakeup)) )
#define PCR←IOGbl←Read	PCR←IOGbl←←Read

#define PCR←IOGbl←←Write(gde,buf,nbyte,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←write))(\
		(gde),(buf),(nbyte),(sigMask),(wakeup)) )
#define PCR←IOGbl←Write	PCR←IOGbl←←Write

#define PCR←IOGbl←←LSeek(gde,offset,whence,where,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←lSeek))(\
		(gde),(offset),(whence),(where),(sigMask),(wakeup)) )
#define PCR←IOGbl←LSeek	PCR←IOGbl←←LSeek

#define PCR←IOGbl←←FStat(gde,sbuf,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fStat))(\
		(gde),(sbuf),(sigMask),(wakeup)) )
#define PCR←IOGbl←FStat	PCR←IOGbl←←FStat


#define PCR←IOGbl←←FPathConf(gde,name,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fPathConf))(\
		(gde),(name),(sigMask),(wakeup)) )
#define PCR←IOGbl←FPathConf	PCR←IOGbl←←FPathConf


#define PCR←IOGbl←←FCntl(gde,cmd,arg,ansp,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fCntl))(\
		(gde),(cmd),(arg),(ansp),(sigMask),(wakeup)) )
#define PCR←IOGbl←FCntl	PCR←IOGbl←←FCntl


#define PCR←IOGbl←←WaitReady(gde,events,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←waitReady))(\
		(gde),(events),(sigMask),(wakeup)) )
#define PCR←IOGbl←WaitReady	PCR←IOGbl←←WaitReady


#define PCR←IOGbl←←GetGenericOpProc(gde) \
	((gde)->gde←gdep->gdep←genericOp)
#define PCR←IOGbl←GetGenericOpProc	PCR←IOGbl←←GetGenericOpProc

#define PCR←IOGbl←←GetGenericCloneProc(gde) \
	((gde)->gde←gdep->gdep←genericClone)
#define PCR←IOGbl←GetGenericCloneProc	PCR←IOGbl←←GetGenericCloneProc



#define PCR←IOGbl←←FSync(gde,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fSync))(\
		(gde),(sigMask),(wakeup)) )
#define PCR←IOGbl←FSync	PCR←IOGbl←←FSync

#define PCR←IOGbl←←FChMod(gde,mode,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fChMod))(\
		(gde),(mode),(sigMask),(wakeup)) )
#define PCR←IOGbl←FChMod	PCR←IOGbl←←FChMod

#define PCR←IOGbl←←FChOwn(gde,owner,group,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fChOwn))(\
		(gde),(owner),(group),(sigMask),(wakeup)) )
#define PCR←IOGbl←FChOwn	PCR←IOGbl←←FChOwn

#define PCR←IOGbl←←FTruncate(gde,length,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←fTruncate))(\
		(gde),(length),(sigMask),(wakeup)) )
#define PCR←IOGbl←FTruncate	PCR←IOGbl←←FTruncate



#define PCR←IOGbl←←Close(gde,sigMask,wakeup) \
	((*((gde)->gde←gdep->gdep←close))(\
		(gde),(sigMask),(wakeup)) )
#define PCR←IOGbl←Close	PCR←IOGbl←←Close


/*
 * Initialization
 *
 * Called from PCR←IOImpl.c
 */

extern PCR←ERes PCR←IOGbl←Setup(void);

extern PCR←ERes PCR←IOGbl←Run(void);

#endif /* ! ←←PCR←IOGbl←h */

/*
$Log$
*/