XrdClientMessage.cc

Go to the documentation of this file.
00001 //////////////////////////////////////////////////////////////////////////
00002 //                                                                      //
00003 // XrdClientMessage                                                     // 
00004 //                                                                      //
00005 // Author: Fabrizio Furano (INFN Padova, 2004)                          //
00006 // Adapted from TXNetFile (root.cern.ch) originally done by             //
00007 //  Alvise Dorigo, Fabrizio Furano                                      //
00008 //          INFN Padova, 2003                                           //
00009 //                                                                      //
00010 // A message coming from a physical connection. I.e. a server response  //
00011 //  or some kind of error                                               //
00012 //                                                                      //
00013 //////////////////////////////////////////////////////////////////////////
00014 
00015 //       $Id: XrdClientMessage.cc 30949 2009-11-02 16:37:58Z ganis $
00016 
00017 const char *XrdClientMessageCVSID = "$Id: XrdClientMessage.cc 30949 2009-11-02 16:37:58Z ganis $";
00018 
00019 #include "XrdClient/XrdClientMessage.hh"
00020 #include "XrdClient/XrdClientProtocol.hh"
00021 #include "XrdClient/XrdClientDebug.hh"
00022 #include "XrdClient/XrdClientPhyConnection.hh"
00023 
00024 #include <stdlib.h> // for malloc
00025 #include <string.h> // for memcpy
00026 
00027 
00028 //__________________________________________________________________________
00029 XrdClientMessage::XrdClientMessage(struct ServerResponseHeader header)
00030 {
00031   // Constructor
00032 
00033   fStatusCode = kXrdMSC_ok;
00034   memcpy((void *)&fHdr, (const void*)&header, sizeof(ServerResponseHeader));
00035   fData = 0;
00036   fMarshalled = false;
00037   if (!CreateData()) {
00038     Error("XrdClientMessage", 
00039           "Error allocating " << fHdr.dlen << " bytes.");
00040     fAllocated = false;
00041   } else 
00042     fAllocated = true;
00043 }
00044 
00045 //__________________________________________________________________________
00046 XrdClientMessage::XrdClientMessage()
00047 {
00048   // Default constructor
00049 
00050   memset(&fHdr, 0, sizeof(fHdr));
00051   fStatusCode = kXrdMSC_ok;
00052   fData = 0;
00053   fMarshalled = false;
00054   fAllocated = false;
00055 }
00056 
00057 //__________________________________________________________________________
00058 XrdClientMessage::~XrdClientMessage()
00059 {
00060   // Destructor
00061 
00062   if (fData)
00063     free(fData);
00064 }
00065 
00066 //__________________________________________________________________________
00067 void *XrdClientMessage::DonateData()
00068 {
00069   // Unlink the owned data in order to pass them elsewhere
00070 
00071   void *res = fData;
00072   fData = 0;
00073   fAllocated = false;
00074   
00075   return (res);
00076 }
00077 
00078 //__________________________________________________________________________
00079 bool XrdClientMessage::CreateData()
00080 {
00081   // Allocate data
00082 
00083   if (!fAllocated) {
00084     if (fHdr.dlen > 0) {
00085 
00086       long pgsz = sysconf(_SC_PAGESIZE);
00087       int memtrbl = 0;
00088       if ((pgsz > 0) && (fHdr.dlen+1 > pgsz))
00089         memtrbl = posix_memalign(&fData, pgsz, fHdr.dlen+1);
00090       else
00091         fData = malloc(fHdr.dlen+1);
00092 
00093       if (!fData || memtrbl) {
00094          Error("XrdClientMessage::CreateData",
00095                "Fatal ERROR *** memory allocation alloc of " <<
00096                fHdr.dlen+1 << " bytes failed."
00097                " Probable system resources exhausted.");
00098          return FALSE;
00099       }
00100       char *tmpPtr = (char *)fData;
00101 
00102       // Useful to get always 0-terminated strings
00103       tmpPtr[fHdr.dlen] = '\0';
00104     }
00105     if (!fData)
00106       return FALSE;
00107     else
00108       return TRUE;
00109   } else
00110     return TRUE;
00111 }
00112 
00113 //__________________________________________________________________________
00114 void XrdClientMessage::Marshall()
00115 {
00116   // Marshall, i.e. put in network byte order
00117 
00118   if (!fMarshalled) {
00119     ServerResponseHeader2NetFmt(&fHdr);
00120     fMarshalled = TRUE;
00121   }
00122 }
00123 
00124 //__________________________________________________________________________
00125 void XrdClientMessage::Unmarshall()
00126 {
00127   // Unmarshall, i.e. from network byte to normal order
00128 
00129   if (fMarshalled) {
00130     clientUnmarshall(&fHdr);
00131     fMarshalled = FALSE;
00132   }
00133 }
00134 
00135 //__________________________________________________________________________
00136 int XrdClientMessage::ReadRaw(XrdClientPhyConnection *phy)
00137 {
00138   // Given a physical connection, we completely build the content
00139   // of the message, reading it from the socket of a phyconn
00140 
00141   int readres;
00142   int readLen = sizeof(ServerResponseHeader);
00143   int usedsubstreamid = 0;
00144 
00145   phy->ReadLock();
00146 
00147   Info(XrdClientDebug::kDUMPDEBUG,
00148        "XrdClientMessage::ReadRaw",
00149        "Reading header (" << readLen << " bytes).");
00150   
00151   // Read a header from any substream and report it
00152   readres = phy->ReadRaw((void *)&fHdr, readLen, -1, &usedsubstreamid);
00153   if (readres == readLen) phy->PauseSelectOnSubstream(usedsubstreamid);
00154 
00155   phy->ReadUnLock();
00156 
00157   if (readres != readLen) {
00158 
00159     if (readres == TXSOCK_ERR_TIMEOUT)
00160       SetStatusCode(kXrdMSC_timeout);
00161     else {
00162       Info(XrdClientDebug::kNODEBUG,"XrdClientMessage::ReadRaw",
00163            "Failed to read header (" << readLen << " bytes).");
00164       SetStatusCode(kXrdMSC_readerr);
00165 
00166     }
00167     memset(&fHdr, 0, sizeof(fHdr));
00168   }
00169 
00170   // the data arrive marshalled from the server (i.e. network byte order)
00171   SetMarshalled(TRUE);
00172   Unmarshall();
00173 
00174   Info(XrdClientDebug::kDUMPDEBUG,
00175        "XrdClientMessage::ReadRaw"," sid: "<<HeaderSID() <<
00176        ", IsAttn: " << IsAttn() <<
00177        ", substreamid: " << usedsubstreamid);
00178 
00179   if (fHdr.dlen > 0) {
00180 
00181     Info(XrdClientDebug::kDUMPDEBUG,
00182          "XrdClientMessage::ReadRaw",
00183          "Reading data (" << fHdr.dlen << " bytes) from substream " << usedsubstreamid);
00184 
00185     if (!CreateData()) {
00186 
00187       Info(XrdClientDebug::kNODEBUG,"XrdClientMessage::ReadRaw",
00188            "Failed to create data (" << fHdr.dlen << " bytes) from substream " <<
00189            usedsubstreamid << ".");
00190 
00191       SetStatusCode(kXrdMSC_timeout);
00192 
00193       memset(&fHdr, 0, sizeof(fHdr));
00194 
00195     } else if (phy->ReadRaw(fData, fHdr.dlen, usedsubstreamid) != fHdr.dlen) {
00196 
00197       Info(XrdClientDebug::kNODEBUG,"XrdClientMessage::ReadRaw",
00198            "Failed to read data (" << fHdr.dlen << " bytes) from substream " <<
00199            usedsubstreamid << ".");
00200 
00201       free( DonateData() );
00202 
00203       if (readres == TXSOCK_ERR_TIMEOUT)
00204         SetStatusCode(kXrdMSC_timeout);
00205       else
00206         SetStatusCode(kXrdMSC_readerr);
00207 
00208       memset(&fHdr, 0, sizeof(fHdr));
00209     }
00210   }
00211   phy->RestartSelectOnSubstream(usedsubstreamid);
00212   //  phy->ReadUnLock();
00213   return 1;
00214 }
00215 
00216 //___________________________________________________________________________
00217 void XrdClientMessage::Int2CharStreamid(kXR_char *charstreamid, short intstreamid)
00218 {
00219   // Converts a streamid given as an integer to its representation
00220   // suitable for the streamid inside the messages (i.e. ascii)
00221 
00222   memcpy(charstreamid, &intstreamid, sizeof(intstreamid));
00223 }
00224 
00225 //___________________________________________________________________________
00226 kXR_unt16 XrdClientMessage::CharStreamid2Int(kXR_char *charstreamid)
00227 {
00228   // Converts a streamid given as an integer to its representation
00229   // suitable for the streamid inside the messages (i.e. ascii)
00230 
00231   kXR_unt16 res = *((short *)charstreamid);
00232 
00233   return res;
00234 }

Generated on Tue Jul 5 14:46:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1