Skip to content

Commit

Permalink
[Posix] Stage 1: Implement async cache interface.
Browse files Browse the repository at this point in the history
  • Loading branch information
abh3 committed Jun 30, 2016
1 parent 7fcca40 commit 4f6de02
Show file tree
Hide file tree
Showing 2 changed files with 316 additions and 0 deletions.
304 changes: 304 additions & 0 deletions src/XrdOuc/XrdOucCache2.hh
@@ -0,0 +1,304 @@
#ifndef __XRDOUCCACHE2_HH__
#define __XRDOUCCACHE2_HH__
/******************************************************************************/
/* */
/* X r d O u c C a c h e 2 . h h */
/* */
/* (c) 2016 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* 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 <http://www.gnu.org/licenses/>. */
/* */
/* 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 "XrdOuc/XrdOucCache.hh"

//-----------------------------------------------------------------------------
//! XrdOucCache2
//!
//! This class is an extension of the original XrdOucCache class and provides
//! async I/O support, defered open and I/O decoupling. It is loaded as a
//! cache plugin by the POSIX package via the proxy directive
//!
//! pss.cache -2 \<path\>
//!
//! Without the "-2" the original version is loaded. Implementation of a cache
//! is similar between versions (see XrdOucCache.hh for details). The only
//! difference is this version requires additional methods to be implemented
//! and uses an asynchrnous callback mechanism to return the results.
//-----------------------------------------------------------------------------

/******************************************************************************/
/* C l a s s X r d O u c C a c h e 2 C B */
/******************************************************************************/

//-----------------------------------------------------------------------------
//! The XrdOucCache2CB defines a callback object that must be used to handle
//! asynchronous operations (e.g. I/O).
//-----------------------------------------------------------------------------

class XrdOucCache2CB
{
public:

//------------------------------------------------------------------------------
//! Handle result from a previous async operation.
//!
//! @param result is result from a previous operation. Successful results are
//! always values >= 0 while errors are negative values and are
//! always '-errno' indicate the reason for the error.
//------------------------------------------------------------------------------
virtual
void Done(int result) = 0;

XrdOucCache2CB() {}
virtual ~XrdOucCache2CB() {}
};

/******************************************************************************/
/* C l a s s X r d O u c C a c h e I O 2 */
/******************************************************************************/

//------------------------------------------------------------------------------
//! The XrdOucCacheIO2 object is responsible for interacting with the original
//! data source/target. It can be used with or without a front-end cache. It
//! an extension of the XrdOucCacheIO class which defines base methods.
//------------------------------------------------------------------------------

class XrdOucCacheIO2 : public virtual XrdOucCacheIO
{
public:

//------------------------------------------------------------------------------
//! Perform an asynchronous file open request. This method is meant to be
//! by the cache layer using the original XrdOucCacheIO2 object passed to
//! Attach() after the cache layer has defered an open request via Prepare().
//! The file is opened using the original url, oflags, and mode.
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread. Done() is passed
//! <0 - Open failed, value is -errno.
//! =0 - Open succeeded.
//------------------------------------------------------------------------------

virtual void Open(XrdOucCache2CB &iocb) {iocb.Done(-ENOSYS);}

//------------------------------------------------------------------------------
//! Perform an asynchronous read (defaults to synchrnous).
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread. Done() is passed
//! < 0 - Read failed, value is -errno.
//! >=0 - Read succeeded, value is number of bytes read.
//! @param buff pointer to the buffer to receive the results. The buffer must
//! remain valid until the callback is invoked.
//! @param offs the offset into the file.
//! @param rlen the number of bytes to read.
//------------------------------------------------------------------------------

using XrdOucCacheIO::Read;

virtual void Read (XrdOucCache2CB &iocb, char *buff, long long offs, int rlen)
{iocb.Done(Read(buff, offs, rlen));}

//------------------------------------------------------------------------------
//! Perform an asynchronous vector read (defaults to synchrnous).
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread. Done() is passed
//! < 0 - ReadV failed, value is -errno.
//! >=0 - ReadV succeeded, value is number of bytes read.
//! @param readV pointer to a vector of read requests.
//! @param rnum the number of elements in the vector.
//------------------------------------------------------------------------------

using XrdOucCacheIO::ReadV;

virtual void ReadV(XrdOucCache2CB &iocb, const XrdOucIOVec *readV, int rnum)
{iocb.Done(ReadV(readV, rnum));}

//------------------------------------------------------------------------------
//! Perform an asynchronous fsync() operation (defaults to synchronous).
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread. Done() is passed
//! <0 - Sync failed, value is -errno.
//! =0 - Sync succeeded.
//------------------------------------------------------------------------------

using XrdOucCacheIO::Sync;

virtual void Sync(XrdOucCache2CB &iocb) {iocb.Done(Sync());}

//------------------------------------------------------------------------------
//! Perform an asynchronous trunc() operation (defaults to synchrnous).
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread. Done() is passsed
//! <0 - Trunc failed, value is -errno.
//! =0 - Trunc succeeded.
//! @param offs the size the file is to have.
//------------------------------------------------------------------------------

using XrdOucCacheIO::Trunc;

virtual void Trunc(XrdOucCache2CB &iocb, long long offs)
{iocb.Done(Trunc(offs));}

//------------------------------------------------------------------------------
//! Perform an asynchronous write (defaults to synchronous).
//!
//! @param iocb reference to the callback object that receives the result. All
//! results are returned via this object's Done() method. If the
//! caller holds any locks they must be recursive locks as the
//! callback may occur on the calling thread.
//! < 0 - Write failed, value is -errno.
//! >=0 - Write succeeded, value is number of bytes written.
//! @param buff pointer to the buffer holding the contents. The buffer must
//! remain valid until the callback is invoked.
//! @param offs the offset into the file.
//! @param wlen the number of bytes to write
//------------------------------------------------------------------------------

using XrdOucCacheIO::Write;

virtual void Write(XrdOucCache2CB &iocb, char *buff, long long offs, int wlen)
{iocb.Done(Write(buff, offs, wlen));}

//------------------------------------------------------------------------------

virtual ~XrdOucCacheIO2() {} // Always use Detach() instead of direct delete!
};

/******************************************************************************/
/* C l a s s X r d O u c C a c h e 2 */
/******************************************************************************/

//------------------------------------------------------------------------------
//! The XrdOucCache2 class is used to define a version 2 cache. In version 2,
//! there can be only one such instance. the cache is associated with one or
//! more XrdOucCacheIO2 objects. Use the Attach() method in this class to
//! create such associations.
//------------------------------------------------------------------------------

class XrdOucCache2 : public virtual XrdOucCache
{
public:

//------------------------------------------------------------------------------
//! Obtain a new XrdOucCacheIO2 object that fronts an existing XrdOucCacheIO2
//! with this cache. Upon success a pointer to a new XrdOucCacheIO2 object is
//! returned and must be used to read and write data with the cache interposed.
//! Upon failure, the original XrdOucCacheIO2 object is returned with errno set.
//! You can continue using the object without any cache.
//!
//! @param ioP Pointer to the current CacheIO2 object used for I/O.
//! @param opts Cache options identical to those defined for XrdOucCache
//! Attach() method.
//!
//! @return Pointer to a new XrdOucCacheIO2 object (success) or the original
//! XrdOucCacheIO2 object (failure) with errno set.
//------------------------------------------------------------------------------
virtual
XrdOucCacheIO2 *Attach(XrdOucCacheIO2 *ioP, int opts=0) = 0;

virtual
XrdOucCacheIO *Attach(XrdOucCacheIO *ioP, int opts=0)
{errno = ENOSYS; return ioP;}

//------------------------------------------------------------------------------
//! Creates an instance of a version 1 cache. This method is no longer used so
//! we simply define a default for this method here for backward compatability.
//!
//! @return A pointer to an XrdOucCache2 object upon success or a nil pointer
//! with errno set upon failure.
//------------------------------------------------------------------------------
virtual
XrdOucCache *Create(Parms &Params, XrdOucCacheIO::aprParms *aprP=0)
{return this;}

//------------------------------------------------------------------------------
//! Preapare the cache for a file open request. This method is called prior to
//! actually opening a file. This method is meant to allow defering an open
//! request or implementing the full I/O stack in the cache layer.
//!
//! @param url - Pointer to the url about to be opened.
//! @param oflags - Standard Unix open flags (see open(2)).
//! @param mode - Standard mode flags if file is being created.
//!
//! @return <0 Error has occurred, return value is -errno; fail open request.
//! =0 Continue with open() request.
//! >0 Defer open but treat the file as actually being open. Use the
//! XrdOucCacheIO2::Open() method to open the file at a later time.
//------------------------------------------------------------------------------
virtual
int Prepare(const char *url, int oflags, mode_t mode)
{(void)url; (void)oflags; (void)mode; return 0;}

XrdOucCache2() {}
virtual ~XrdOucCache2() {}
};

/******************************************************************************/
/* C r e a t i n g C a c h e P l u g - I n s */
/******************************************************************************/

//------------------------------------------------------------------------------
//! You can create a V2 cache plug-in for those parts of the xrootd system that
//! allow a dynamically selectable cache implementation (e.g. the proxy server
//! plug-in supports cache plug-ins via the pss.cachelib). For the proxy server,
//! it preferentially looks for XrdOucGetCache2() and invokes this function if
//! is exists. Otherwise, it uses the XrdOucGetCache() function (old version 1).
//!
//! Your plug-in must exist in a shared library and have the following extern C
//! function defined whos parameters are:
//!
//! @param Logger Pointer to the logger object that should be used with an
//! instance of XrdSysError to direct messages to a log file.
//! If Logger is null, you should use cerr to output messages.
//! @param Config Pointer to the configuration file name from where you
//! should get additional information. If Config is null, there
//! is no configuration file is present.
//! @param Parms Pointer to any parameters specified after the shared library
//! path. If Parms is null, there are no parameters.
//! @return A usable, fully configured, instance of an XrdOucCache2
//! object upon success and a null pointer otherwise. This
//! instance is used for all operations defined by methods in
//! XrdOucCache bas class as well as this class.
//!
//! extern "C"
//! {
//! XrdOucCache2 *XrdOucGetCache2(XrdSysLogger *Logger, // Where messages go
//! const char *Config, // Config file used
//! const char *Parms); // Optional parm string
//! }
#endif
12 changes: 12 additions & 0 deletions src/XrdOuc/XrdOucIOVec.hh
Expand Up @@ -44,4 +44,16 @@ struct XrdOucIOVec
int info; // Available for arbitrary use
char *data; // Location to read into.
};

// Add backward compatible constructor to XrdOucIOVec
//
struct XrdOucIOVec2 : public XrdOucIOVec
{
XrdOucIOVec2(char *buff, long long offs, int sz, int inf=0)
{XrdOucIOVec::offset = offs;
XrdOucIOVec::size = sz;
XrdOucIOVec::info = inf;
XrdOucIOVec::data = buff;
}
};
#endif

0 comments on commit 4f6de02

Please sign in to comment.