18 #include "XProtocol/XProtocol.hh"
19 #include "XrdClient/XrdClientConn.hh"
20 #include "XrdClient/XrdClientProtocol.hh"
21 #include "XrdClient/XrdClientConst.hh"
22 #include "XrdClient/XrdClientSid.hh"
23 #include "XrdClient/XrdClientEnv.hh"
45 vector<IOPosBuffer> new_buf;
53 return readv(&(new_buf[0]), n);
74 XrdClientConn *xrdc =
m_client->GetClientConn();
75 if (xrdc) {xrdc->SetOpTimeLimit(EnvGetLong(NAME_TRANSACTIONTIMEOUT));}
83 readahead_list read_chunk_list[READV_MAXCHUNKS];
84 char *result_list[READV_MAXCHUNKS];
86 IOSize readv_total_len = 0;
93 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')[" <<
i
94 <<
"].size=" << len <<
" exceeds read size limit 0x7fffffff";
101 char *chunk_data =
static_cast<char *
>(into[
i].
data());
104 IOSize chunk_size = len > READV_MAXCHUNKSIZE ? READV_MAXCHUNKSIZE : len;
106 readv_total_len += chunk_size;
107 read_chunk_list[chunk_off].rlen = chunk_size;
108 read_chunk_list[chunk_off].offset = off;
109 result_list[chunk_off] = chunk_data;
110 chunk_data += chunk_size;
112 memcpy(&(read_chunk_list[chunk_off].fhandle), handle, 4);
114 if (chunk_off == READV_MAXCHUNKS) {
117 IOSize tmp_total_len =
readv_send(result_list, *read_chunk_list, chunk_off, readv_total_len);
118 total_len += tmp_total_len;
119 if (
unlikely(tmp_total_len != readv_total_len))
122 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')"
123 <<
".size=" << n <<
" Chunk of " << readv_total_len <<
" requested but "
124 << tmp_total_len <<
" bytes returned by server.";
136 IOSize tmp_total_len =
readv_send(result_list, *read_chunk_list, chunk_off, readv_total_len);
137 if (
unlikely(tmp_total_len != readv_total_len))
140 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')"
141 <<
".size=" << n <<
" Chunk of " << readv_total_len <<
" requested but "
142 << tmp_total_len <<
" bytes returned by server.";
147 total_len += tmp_total_len;
167 XrdClientConn *xrdc =
m_client->GetClientConn();
168 ClientRequest readvFileRequest;
169 memset( &readvFileRequest, 0,
sizeof(readvFileRequest) );
172 memcpy(readvFileRequest.header.streamid, &sid,
sizeof(kXR_unt16));
173 readvFileRequest.header.requestid = kXR_readv;
174 readvFileRequest.readv.dlen = n *
sizeof(
struct readahead_list);
176 std::vector<char> res_buf;
177 res_buf.reserve( total_len + (n *
sizeof(
struct readahead_list)) );
180 clientMarshallReadAheadList(&read_chunk_list, readvFileRequest.readv.dlen);
185 success = xrdc->SendGenCommand(&readvFileRequest, &read_chunk_list, 0,
186 (
void *)&(res_buf[0]),
FALSE, (
char *)
"ReadV");
187 data_length = xrdc->LastServerResp.dlen;
189 clientUnMarshallReadAheadList(&read_chunk_list, readvFileRequest.readv.dlen);
194 return readv_unpack(result_list, res_buf, data_length, read_chunk_list, n);
207 IOSize response_offset = 0;
211 if (
unlikely(response_offset +
sizeof(
struct readahead_list) > response_length)) {
213 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')[" <<
i
214 <<
"] returned an incorrectly-sized response (short header)";
222 const readahead_list *response =
reinterpret_cast<struct readahead_list*
>(&result_buf[response_offset]);
223 offset = ntohll(response->offset);
224 rlen = ntohl(response->rlen);
229 if (
unlikely((&read_chunk_list)[
i].offset != offset)) {
231 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')[" <<
i
232 <<
"] returned offset " << offset <<
" does not match requested offset "
233 << (&read_chunk_list)[
i].offset;
238 if (
unlikely((&read_chunk_list)[
i].rlen != rlen)) {
240 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')[" <<
i
241 <<
"] returned size " << rlen <<
" does not match requested size "
242 << (&read_chunk_list)[
i].rlen;
247 if (
unlikely(response_offset + rlen > response_length)) {
249 ex <<
"XrdFile::readv(name='" <<
m_name <<
"')[" <<
i
250 <<
"] returned an incorrectly-sized response (short data)";
255 response_offset +=
sizeof(
struct readahead_list);
258 memcpy(result_list[
i], &result_buf[response_offset], rlen);
259 response_offset += rlen;
static boost::mutex mutex
IOSize readv_send(char **result_buffer, readahead_list &read_chunk_list, IOSize n, IOSize total_len)
virtual IOSize readv(IOBuffer *into, IOSize n)
unsigned int offset(bool)
IOOffset offset(void) const
pthread_mutex_t & m_mutex
virtual IOOffset size(void) const
void addContext(std::string const &context)
pthread_mutex_t m_readv_mutex
IOSize readv_unpack(char **result_buffer, std::vector< char > &res_buf, IOSize datalen, readahead_list &read_chunk_list, IOSize n)
char data[epos_bytes_allocation]
void addConnection(cms::Exception &)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of FALSE
MutexSentry(pthread_mutex_t &mutex)