Skip to content

Commit 8971937

Browse files
Merge pull request #57 from M1eyu2018/add-pread-for-client
Set infoMutex more proper
2 parents 833952f + 57e07b8 commit 8971937

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/client/InputStreamImpl.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ InputStreamImpl::InputStreamImpl() :
135135

136136
InputStreamImpl::InputStreamImpl(shared_ptr<LocatedBlocks> lbsPtr) {
137137
new (this)InputStreamImpl();
138+
lock_guard<std::recursive_mutex> lock(infoMutex);
138139
lbs = lbsPtr;
139140
}
140141

@@ -223,6 +224,7 @@ void InputStreamImpl::updateBlockInfos() {
223224
* @param need Whether getBlockLocations needs to be called.
224225
*/
225226
void InputStreamImpl::updateBlockInfos(bool need) {
227+
lock_guard<std::recursive_mutex> lock(infoMutex);
226228
int retry = maxGetBlockInfoRetry;
227229

228230
for (int i = 0; i < retry; ++i) {
@@ -232,7 +234,6 @@ void InputStreamImpl::updateBlockInfos(bool need) {
232234
}
233235

234236
if (need) {
235-
lock_guard<std::recursive_mutex> lock(infoMutex);
236237
filesystem->getBlockLocations(path, cursor, prefetchSize, *lbs);
237238
}
238239

@@ -714,6 +715,7 @@ int32_t InputStreamImpl::readOneBlock(char * buf, int32_t size, bool shouldUpdat
714715
*/
715716
int32_t InputStreamImpl::readInternal(char * buf, int32_t size) {
716717
int updateMetadataOnFailure = conf->getMaxReadBlockRetry();
718+
bool isInfoMutexLock = false;
717719

718720
try {
719721
do {
@@ -729,6 +731,10 @@ int32_t InputStreamImpl::readInternal(char * buf, int32_t size) {
729731
* Do RPC failover work in updateBlockInfos.
730732
*/
731733
updateBlockInfos();
734+
if (isInfoMutexLock) {
735+
isInfoMutexLock = false;
736+
infoMutex.unlock();
737+
}
732738

733739
/*
734740
* We already have the up-to-date block information,
@@ -768,6 +774,8 @@ int32_t InputStreamImpl::readInternal(char * buf, int32_t size) {
768774
* We will update metadata once and try again.
769775
*/
770776
if (retval < 0) {
777+
infoMutex.lock();
778+
isInfoMutexLock = true;
771779
lbs.reset();
772780
endOfCurBlock = 0;
773781
--updateMetadataOnFailure;
@@ -780,13 +788,26 @@ int32_t InputStreamImpl::readInternal(char * buf, int32_t size) {
780788
continue;
781789
}
782790

791+
if (isInfoMutexLock) {
792+
isInfoMutexLock = false;
793+
infoMutex.unlock();
794+
}
783795
return retval;
784796
} while (true);
785797
} catch (const HdfsCanceled & e) {
798+
if (isInfoMutexLock) {
799+
infoMutex.unlock();
800+
}
786801
throw;
787802
} catch (const HdfsEndOfStream & e) {
803+
if (isInfoMutexLock) {
804+
infoMutex.unlock();
805+
}
788806
throw;
789807
} catch (const HdfsException & e) {
808+
if (isInfoMutexLock) {
809+
infoMutex.unlock();
810+
}
790811
/*
791812
* wrap the underlying error and rethrow.
792813
*/
@@ -806,8 +827,14 @@ int32_t InputStreamImpl::readInternal(char * buf, int32_t size) {
806827
int32_t InputStreamImpl::preadInternal(char * buf, int32_t size, int64_t position) {
807828
int64_t cursor = position;
808829
try {
830+
infoMutex.lock();
831+
if (!lbs) {
832+
THROW(HdfsIOException, "InputStreamImpl: lbs is empty, cannot pread file: %s, from position %" PRId64 ", size: %d.",
833+
path.c_str(), cursor, size);
834+
}
809835
int64_t filelen = getFileLength();
810836
if ((position < 0) || (position >= filelen)) {
837+
infoMutex.unlock();
811838
return -1;
812839
}
813840
int32_t realLen = size;
@@ -818,6 +845,7 @@ int32_t InputStreamImpl::preadInternal(char * buf, int32_t size, int64_t positio
818845
// determine the block and byte range within the block
819846
// corresponding to position and realLen
820847
std::vector<shared_ptr<LocatedBlock>> blockRange = getBlockRange(position, (int64_t)realLen);
848+
infoMutex.unlock();
821849
int32_t remaining = realLen;
822850
int32_t bytesHasRead = 0;
823851
for (shared_ptr<LocatedBlock> blk : blockRange) {
@@ -842,7 +870,7 @@ int32_t InputStreamImpl::preadInternal(char * buf, int32_t size, int64_t positio
842870
* wrap the underlying error and rethrow.
843871
*/
844872
NESTED_THROW(HdfsIOException,
845-
"InputStreamImpl: cannot read file: %s, from position %" PRId64 ", size: %d.",
873+
"InputStreamImpl: cannot pread file: %s, from position %" PRId64 ", size: %d.",
846874
path.c_str(), cursor, size);
847875
}
848876
}
@@ -857,12 +885,12 @@ int32_t InputStreamImpl::preadInternal(char * buf, int32_t size, int64_t positio
857885
* @throws IOException
858886
*/
859887
std::vector<shared_ptr<LocatedBlock>> InputStreamImpl::getBlockRange(int64_t offset, int64_t length) {
888+
lock_guard<std::recursive_mutex> lock(infoMutex);
860889
// getFileLength(): returns total file length
861890
// locatedBlocks.getFileLength(): returns length of completed blocks
862891
if (offset >= getFileLength()) {
863892
THROW(HdfsIOException, "Offset: %" PRId64 " exceeds file length: %" PRId64, offset, getFileLength());
864893
}
865-
lock_guard<std::recursive_mutex> lock(infoMutex);
866894
std::vector<shared_ptr<LocatedBlock>> blocks;
867895
int64_t lengthOfCompleteBlk = lbs->getFileLength();
868896
bool readOffsetWithinCompleteBlk = offset < lengthOfCompleteBlk;
@@ -1185,7 +1213,9 @@ void InputStreamImpl::close() {
11851213
prefetchSize = 0;
11861214
blockReader.reset();
11871215
curBlock.reset();
1216+
infoMutex.lock();
11881217
lbs.reset();
1218+
infoMutex.unlock();
11891219
conf.reset();
11901220
failedNodes.clear();
11911221
path.clear();

0 commit comments

Comments
 (0)