00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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>
00025 #include <string.h>
00026
00027
00028
00029 XrdClientMessage::XrdClientMessage(struct ServerResponseHeader header)
00030 {
00031
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
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
00061
00062 if (fData)
00063 free(fData);
00064 }
00065
00066
00067 void *XrdClientMessage::DonateData()
00068 {
00069
00070
00071 void *res = fData;
00072 fData = 0;
00073 fAllocated = false;
00074
00075 return (res);
00076 }
00077
00078
00079 bool XrdClientMessage::CreateData()
00080 {
00081
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
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
00117
00118 if (!fMarshalled) {
00119 ServerResponseHeader2NetFmt(&fHdr);
00120 fMarshalled = TRUE;
00121 }
00122 }
00123
00124
00125 void XrdClientMessage::Unmarshall()
00126 {
00127
00128
00129 if (fMarshalled) {
00130 clientUnmarshall(&fHdr);
00131 fMarshalled = FALSE;
00132 }
00133 }
00134
00135
00136 int XrdClientMessage::ReadRaw(XrdClientPhyConnection *phy)
00137 {
00138
00139
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
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
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
00213 return 1;
00214 }
00215
00216
00217 void XrdClientMessage::Int2CharStreamid(kXR_char *charstreamid, short intstreamid)
00218 {
00219
00220
00221
00222 memcpy(charstreamid, &intstreamid, sizeof(intstreamid));
00223 }
00224
00225
00226 kXR_unt16 XrdClientMessage::CharStreamid2Int(kXR_char *charstreamid)
00227 {
00228
00229
00230
00231 kXR_unt16 res = *((short *)charstreamid);
00232
00233 return res;
00234 }