#ifndef _XROOTD_FILE_H_
#define _XROOTD_FILE_H_
/******************************************************************************/
/* */
/* X r d X r o o t d F i l e . h h */
/* */
/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD 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 Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include "XProtocol/XPtypes.hh"
#include "XrdSys/XrdSysPthread.hh"
#include "XrdXrootd/XrdXrootdFileStats.hh"
/******************************************************************************/
/* X r d X r o o t d F i l e H P */
/******************************************************************************/
class XrdXrootdFileHP
{
public:
void Avail(int fHandle) {fhMutex.Lock();
bool done = (1 == refs--);
if (noMore)
{fhMutex.UnLock();
if (done) delete this;
} else {
fhAvail.push_back(fHandle);
fhMutex.UnLock();
}
}
void Delete() {fhMutex.Lock();
if (!refs) {fhMutex.UnLock(); delete this;}
else {noMore = true; fhMutex.UnLock();}
}
int Get() {int fh;
fhMutex.Lock();
if (fhAvail.empty()) fh = -1;
else {fh = fhAvail.back();
fhAvail.pop_back();
}
fhMutex.UnLock();
return fh;
}
void Ref() {fhMutex.Lock(); refs++; fhMutex.UnLock();}
XrdXrootdFileHP(int rsv=2) : refs(1), noMore(false)
{fhAvail.reserve(rsv);}
private:
~XrdXrootdFileHP() {}
XrdSysMutex fhMutex;
std::vector fhAvail;
int refs;
bool noMore;
};
/******************************************************************************/
/* X r d X r o o t d F i l e */
/******************************************************************************/
class XrdSfsFile;
class XrdXrootdFileLock;
class XrdXrootdMonitor;
class XrdXrootdFile
{
public:
XrdSfsFile *XrdSfsp; // -> Actual file object
union {char *mmAddr; // Memory mapped location, if any
unsigned
long long cbArg; // Callback argument upon close()
};
char *FileKey; // -> File hash name (actual file name now)
char FileMode; // 'r' or 'w'
char AsyncMode; // 1 -> if file in async r/w mode
char isMMapped; // 1 -> file is memory mapped
char sfEnabled; // 1 -> file is sendfile enabled
union {int fdNum; // File descriptor number if regular file
int fHandle; // The file handle upon close()
};
XrdXrootdFileHP *fhProc; // File handle processor (set at close time)
const char *ID; // File user
XrdXrootdFileStats Stats; // File access statistics
static void Init(XrdXrootdFileLock *lp, XrdSysError *erP, int sfok);
XrdXrootdFile(const char *id, const char *path, XrdSfsFile *fp,
char mode='r', bool async=false, int sfOK=0,
struct stat *sP=0);
~XrdXrootdFile();
private:
int bin2hex(char *outbuff, char *inbuff, int inlen);
static XrdXrootdFileLock *Locker;
static int sfOK;
static const char *TraceID;
};
/******************************************************************************/
/* X r d X r o o t d F i l e T a b l e */
/******************************************************************************/
// The before define the structure of the file table. We will have FTABSIZE
// internal table entries. We will then provide an external linear table
// that increases by FTABSIZE entries. There is one file table per link and
// it is owned by the base protocol object.
//
#define XRD_FTABSIZE 16
// WARNING! Manipulation (i.e., Add/Del/delete) of this object must be
// externally serialized at the link level. Only one thread
// may be active w.r.t this object during manipulation!
//
class XrdXrootdFileTable
{
public:
int Add(XrdXrootdFile *fp);
XrdXrootdFile *Del(XrdXrootdMonitor *monP, int fnum, bool dodel=true);
inline XrdXrootdFile *Get(int fnum)
{if (fnum >= 0)
{if (fnum < XRD_FTABSIZE) return FTab[fnum];
if (XTab && (fnum-XRD_FTABSIZE)