CMS 3D CMS Logo

Public Member Functions | Private Attributes

DCacheFile Class Reference

#include <DCacheFile.h>

Inheritance diagram for DCacheFile:
Storage IOInput IOOutput

List of all members.

Public Member Functions

virtual void abort (void)
virtual void close (void)
virtual void create (const char *name, bool exclusive=false, int perms=0666)
virtual void create (const std::string &name, bool exclusive=false, int perms=0666)
 DCacheFile (const std::string &name, int flags=IOFlags::OpenRead, int perms=0666)
 DCacheFile (IOFD fd)
 DCacheFile (const char *name, int flags=IOFlags::OpenRead, int perms=0666)
 DCacheFile (void)
virtual void open (const char *name, int flags=IOFlags::OpenRead, int perms=0666)
virtual void open (const std::string &name, int flags=IOFlags::OpenRead, int perms=0666)
virtual IOOffset position (IOOffset offset, Relative whence=SET)
virtual IOSize read (void *into, IOSize n)
virtual IOSize readv (IOPosBuffer *into, IOSize buffers)
virtual IOSize readv (IOBuffer *into, IOSize buffers)
virtual void resize (IOOffset size)
virtual IOSize write (const void *from, IOSize n)
 ~DCacheFile (void)

Private Attributes

bool m_close
IOFD m_fd
std::string m_name

Detailed Description

Definition at line 8 of file DCacheFile.h.


Constructor & Destructor Documentation

DCacheFile::DCacheFile ( void  )

Definition at line 11 of file DCacheFile.cc.

  : m_fd (EDM_IOFD_INVALID),
    m_close (false)
{}
DCacheFile::DCacheFile ( IOFD  fd)

Definition at line 16 of file DCacheFile.cc.

  : m_fd (fd),
    m_close (true)
{}
DCacheFile::DCacheFile ( const char *  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 21 of file DCacheFile.cc.

References open().

  : m_fd (EDM_IOFD_INVALID),
    m_close (false)
{ open (name, flags, perms); }
DCacheFile::DCacheFile ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
)

Definition at line 28 of file DCacheFile.cc.

References flags, and open().

  : m_fd (EDM_IOFD_INVALID),
    m_close (false)
{ open (name.c_str (), flags, perms); }
DCacheFile::~DCacheFile ( void  )

Definition at line 35 of file DCacheFile.cc.

References m_close, and m_name.

{
  if (m_close)
    edm::LogError("DCacheFileError")
      << "Destructor called on dCache file '" << m_name
      << "' but the file is still open";
}

Member Function Documentation

void DCacheFile::abort ( void  ) [virtual]

Definition at line 180 of file DCacheFile.cc.

References EDM_IOFD_INVALID, m_close, and m_fd.

{
  if (m_fd != EDM_IOFD_INVALID)
    dc_close (m_fd);

  m_close = false;
  m_fd = EDM_IOFD_INVALID;
}
void DCacheFile::close ( void  ) [virtual]

Reimplemented from Storage.

Definition at line 154 of file DCacheFile.cc.

References EDM_IOFD_INVALID, m_close, m_fd, and m_name.

Referenced by open().

{
  if (m_fd == EDM_IOFD_INVALID)
  {
    edm::LogError("DCacheFileError")
      << "DCacheFile::close(name='" << m_name
      << "') called but the file is not open";
    m_close = false;
    return;
  }

  dc_errno = 0;
  if (dc_close (m_fd) == -1)
    edm::LogWarning("DCacheFileWarning")
      << "dc_close(name='" << m_name
      << "') failed with error '" << dc_strerror (dc_errno)
      << "' (dc_errno=" << dc_errno << ")";

  m_close = false;
  m_fd = EDM_IOFD_INVALID;

  // Caused hang.  Will be added back after problem is fixed.
  // edm::LogInfo("DCacheFileInfo") << "Closed " << m_name;
}
void DCacheFile::create ( const char *  name,
bool  exclusive = false,
int  perms = 0666 
) [virtual]
void DCacheFile::create ( const std::string &  name,
bool  exclusive = false,
int  perms = 0666 
) [virtual]
void DCacheFile::open ( const std::string &  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
) [virtual]

Definition at line 67 of file DCacheFile.cc.

References flags, and open().

{ open (name.c_str (), flags, perms); }
void DCacheFile::open ( const char *  name,
int  flags = IOFlags::OpenRead,
int  perms = 0666 
) [virtual]

Definition at line 73 of file DCacheFile.cc.

References cms::Exception::addContext(), close(), EDM_IOFD_INVALID, edm::errors::FileOpenError, m_close, m_fd, m_name, mergeVDriftHistosByStation::name, O_NONBLOCK, IOFlags::OpenAppend, IOFlags::OpenCreate, IOFlags::OpenExclusive, IOFlags::OpenNonBlock, IOFlags::OpenRead, IOFlags::OpenTruncate, IOFlags::OpenUnbuffered, and IOFlags::OpenWrite.

Referenced by create(), DCacheFile(), and open().

{
  // Actual open
  if ((name == 0) || (*name == 0)) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "Cannot open a file without a name";
    ex.addContext("Calling DCacheFile::open()");
    throw ex;
  }

  if ((flags & (IOFlags::OpenRead | IOFlags::OpenWrite)) == 0) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "Must open file '" << name << "' at least for read or write";
    ex.addContext("Calling DCacheFile::open()");
    throw ex;
  }

  // If I am already open, close old file first
  if (m_fd != EDM_IOFD_INVALID && m_close)
    close ();

  // Translate our flags to system flags
  int openflags = 0;

  if ((flags & IOFlags::OpenRead) && (flags & IOFlags::OpenWrite))
    openflags |= O_RDWR;
  else if (flags & IOFlags::OpenRead)
    openflags |= O_RDONLY;
  else if (flags & IOFlags::OpenWrite)
    openflags |= O_WRONLY;

  if (flags & IOFlags::OpenNonBlock)
    openflags |= O_NONBLOCK;

  if (flags & IOFlags::OpenAppend)
    openflags |= O_APPEND;

  if (flags & IOFlags::OpenCreate)
    openflags |= O_CREAT;

  if (flags & IOFlags::OpenExclusive)
    openflags |= O_EXCL;

  if (flags & IOFlags::OpenTruncate)
    openflags |= O_TRUNC;

  IOFD newfd = EDM_IOFD_INVALID;
  dc_errno = 0;
  if ((newfd = dc_open (name, openflags, perms)) == -1) {
    edm::Exception ex(edm::errors::FileOpenError);
    ex << "dc_open(name='" << name
       << "', flags=0x" << std::hex << openflags
       << ", permissions=0" << std::oct << perms << std::dec
       << ") => error '" << dc_strerror(dc_errno)
       << "' (dc_errno=" << dc_errno << ")";
    ex.addContext("Calling DCacheFile::open()");
    throw ex;
  }

  m_name = name;
  m_fd = newfd;

  // Turn off read-ahead, or adjust read-ahead size depending on
  // whether buffering has been requested.  This is a very tricky
  // balance here.  Without read-ahead data processing appears to
  // become exceedingly slow, and with default (1MB) read-ahead
  // it appears to saturate disk servers and network.  Try tread
  // reasonable middle ground here.
  if (flags & IOFlags::OpenUnbuffered)
    dc_noBuffering(m_fd);
  else
    dc_setBufferSize(m_fd, 64000);

  m_close = true;

  edm::LogInfo("DCacheFileInfo") << "Opened " << m_name;
}
IOOffset DCacheFile::position ( IOOffset  offset,
Relative  whence = SET 
) [virtual]

Implements Storage.

Definition at line 338 of file DCacheFile.cc.

References cms::Exception::addContext(), Storage::CURRENT, EDM_IOFD_INVALID, Storage::END, m_fd, m_name, query::result, and Storage::SET.

{
  if (m_fd == EDM_IOFD_INVALID) {
    cms::Exception ex("FilePositionError");
    ex << "DCacheFile::position() called on a closed file";
    throw ex;
  }
  if (whence != CURRENT && whence != SET && whence != END) {
    cms::Exception ex("FilePositionError");
    ex << "DCacheFile::position() called with incorrect 'whence' parameter";
    throw ex;
  }
  IOOffset      result;
  int           mywhence = (whence == SET ? SEEK_SET
                            : whence == CURRENT ? SEEK_CUR
                            : SEEK_END);

  dc_errno = 0;
  if ((result = dc_lseek64 (m_fd, offset, mywhence)) == -1) {
    cms::Exception ex("FilePositionError");
    ex << "dc_lseek64(name='" << m_name << "', offset=" << offset
       << ", whence=" << mywhence << ") failed with error '"
       << dc_strerror (dc_errno) << "' (dc_errno=" << dc_errno << ")";
    ex.addContext("Calling DCacheFile::position()");
    throw ex;
  }
  // FIXME: dCache returns incorrect value on SEEK_END.
  // Remove this hack when dcap has been fixed.
  if (whence == SEEK_END && (result = dc_lseek64 (m_fd, result, SEEK_SET)) == -1) {
    cms::Exception ex("FilePositionError");
    ex << "dc_lseek64(name='" << m_name << "', offset=" << offset
       << ", whence=" << SEEK_SET << ") failed with error '"
       << dc_strerror (dc_errno) << "' (dc_errno=" << dc_errno << ")";
    ex.addContext("Calling DCacheFile::position()");
    throw ex;
  }
  return result;
}
IOSize DCacheFile::read ( void *  into,
IOSize  n 
) [virtual]

Read into into at most n number of bytes.

If this is a blocking stream, the call will block until some data can be read, end of input is reached, or an exception is thrown. For a non-blocking stream the available input is returned. If none is available, an exception is thrown.

Returns:
The number of bytes actually read. This is less or equal to the size of the buffer. Zero indicates that the end of the input has been reached: end of file, or remote end closing for a connected channel like a pipe or a socket. Otherwise the value can be less than requested if limited amount of input is currently available for platform or implementation reasons.
Exceptions:
Incase of error, a #IOError exception is thrown. This includes the situation where the input stream is in non-blocking mode and no input is currently available (FIXME: make this simpler; clarify which exception).

Implements IOInput.

Definition at line 206 of file DCacheFile.cc.

References cms::Exception::addContext(), BUGLINE, run_regression::done, edm::errors::FileReadError, m_fd, m_name, and alignCSCRings::s.

{
  IOSize done = 0;
  while (done < n)
  {
    dc_errno = 0;
    ssize_t s = dc_read (m_fd, (char *) into + done, n - done);
    if (s == -1) {
      edm::Exception ex(edm::errors::FileReadError);
      ex << "dc_read(name='" << m_name << "', n=" << (n-done)
         << ") failed with error '" << dc_strerror(dc_errno)
         << "' (dc_errno=" << dc_errno << ")";
      ex.addContext("Calling DCacheFile::read()");
      throw ex;
    }
    else if (s == 0)
      // end of file
      break;
    else if (s < ssize_t (n-done))
      edm::LogInfo("DCacheFileWarning")
        << "dc_read(name='" << m_name << "', n=" << (n-done)
        << ") returned a short read of " << s << " bytes; "
        << "please report a bug in dCache referencing the "
        << "comment on line " << BUGLINE << " of " << __FILE__;
    done += s;
  }

  return done;
}
IOSize DCacheFile::readv ( IOPosBuffer into,
IOSize  buffers 
) [virtual]

Reimplemented from Storage.

Definition at line 300 of file DCacheFile.cc.

References cms::Exception::addContext(), AlCaHLTBitMon_QueryRunRegistry::data, edm::errors::FileReadError, i, m_fd, m_name, n, IOPosBuffer::offset(), and IOPosBuffer::size().

{
  assert (! buffers || into);

  // readv may not support zero buffers.
  if (! buffers)
    return 0;

  // Convert the buffers to system format.
  std::vector<iovec2> bufs (buffers);
  for (IOSize i = 0; i < buffers; ++i)
  {
    bufs [i].offset = into [i].offset ();
    bufs [i].len    = into [i].size ();
    bufs [i].buf    = (char *) into [i].data ();
  }

  // Read as long as signals cancel the read before doing anything.
  dc_errno = 0;
  ssize_t n = dc_readv2 (m_fd, &bufs [0], buffers);

  // If it was serious error, throw it.
  if (n == -1) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "dc_readv2(name='" << m_name << "', iov2[" << buffers
       << "]) failed with error '" << dc_strerror(dc_errno)
       << "' (dc_errno=" << dc_errno << ")";
    ex.addContext("Calling DCacheFile::readv()");
    throw ex;
  }
  // Return the number of bytes actually read.
  return n;
}
IOSize DCacheFile::readv ( IOBuffer into,
IOSize  buffers 
) [virtual]

Read from the input stream into multiple scattered buffers. There are buffers to fill in an array starting at into; the memory those buffers occupy does not need to be contiguous. The buffers are filled in the order given, eac buffer is filled fully before the subsequent buffers.

If this is a blocking stream, the call will block until some data can be read, end of input is reached, or an exception is thrown. For a non-blocking stream the available input is returned. If none is available, an exception is thrown.

The base class implementation uses read(void *, IOSize) method, but derived classes may implement a more efficient alternative.

Returns:
The number of bytes actually read. This is less or equal to the size of the buffer. Zero indicates that the end of the input has been reached: end of file, or remote end closing for a connected channel like a pipe or a socket. Otherwise the value can be less than requested if limited amount of input is currently available for platform or implementation reasons. Note that the return value indicates the number of bytes read, not the number of buffers; it is the sum total of bytes filled into all the buffers.
Exceptions:
Incase of error, a #IOError exception is thrown. However if some data has already been read, the error is swallowed and the method returns the data read so far. It is assumed that persistent errors will occur anyway on the next read and sporadic errors like stream becoming unvailable can be ignored. Use xread() if a different policy is desirable.

Reimplemented from IOInput.

Definition at line 265 of file DCacheFile.cc.

References cms::Exception::addContext(), AlCaHLTBitMon_QueryRunRegistry::data, edm::errors::FileReadError, i, m_fd, m_name, n, and IOBuffer::size().

{
  assert (! buffers || into);

  // readv may not support zero buffers.
  if (! buffers)
    return 0;

  // Convert the buffers to system format.
  std::vector<iovec> bufs (buffers);
  for (IOSize i = 0; i < buffers; ++i)
  {
    bufs [i].iov_len  = into [i].size ();
    bufs [i].iov_base = (caddr_t) into [i].data ();
  }

  // Read as long as signals cancel the read before doing anything.
  dc_errno = 0;
  ssize_t n = dc_readv (m_fd, &bufs [0], buffers);

  // If it was serious error, throw it.
  if (n == -1) {
    edm::Exception ex(edm::errors::FileReadError);
    ex << "dc_readv(name='" << m_name << "', iov[" << buffers
       << "]) failed with error '" << dc_strerror(dc_errno)
       << "' (dc_errno=" << dc_errno << ")";
    ex.addContext("Calling DCacheFile::readv()");
    throw ex;
  }

  // Return the number of bytes actually read.
  return n;
}
void DCacheFile::resize ( IOOffset  size) [virtual]

Implements Storage.

Definition at line 378 of file DCacheFile.cc.

References m_name.

{
  cms::Exception ex("FileResizeError");
  ex << "DCacheFile::resize(name='" << m_name << "') not implemented";
  throw ex;
}
IOSize DCacheFile::write ( const void *  from,
IOSize  n 
) [virtual]

Write n bytes of data starting at address from.

Returns:
The number of bytes written. Normally this will be n, but can be less, even zero, for example if the stream is non-blocking mode and cannot accept input at this time.
Exceptions:
Incase of error, an exception is thrown. However if the stream is in non-blocking mode and cannot accept output, it will not throw an exception -- the return value will be less than requested.

Implements IOOutput.

Definition at line 237 of file DCacheFile.cc.

References cms::Exception::addContext(), BUGLINE, run_regression::done, m_fd, m_name, and alignCSCRings::s.

{
  IOSize done = 0;
  while (done < n)
  {
    dc_errno = 0;
    ssize_t s = dc_write (m_fd, (const char *) from + done, n - done);
    if (s == -1) {
      cms::Exception ex("FileWriteError");
      ex << "dc_write(name='" << m_name << "', n=" << (n-done)
         << ") failed with error '" << dc_strerror(dc_errno)
         << "' (dc_errno=" << dc_errno << ")";
      ex.addContext("Calling DCacheFile::write()");
      throw ex;
    }
    else if (s < ssize_t (n-done))
      edm::LogInfo("DCacheFileWarning")
        << "dc_write(name='" << m_name << "', n=" << (n-done)
        << ") returned a short write of " << s << " bytes; "
        << "please report a bug in dCache referencing the "
        << "comment on line " << BUGLINE << " of " << __FILE__;
    done += s;
  }

  return done;
}

Member Data Documentation

bool DCacheFile::m_close [private]

Definition at line 47 of file DCacheFile.h.

Referenced by abort(), close(), open(), and ~DCacheFile().

Definition at line 46 of file DCacheFile.h.

Referenced by abort(), close(), open(), position(), read(), readv(), and write().

std::string DCacheFile::m_name [private]

Definition at line 48 of file DCacheFile.h.

Referenced by close(), open(), position(), read(), readv(), resize(), write(), and ~DCacheFile().