Commit 55902e2f authored by Bill Lorensen's avatar Bill Lorensen

BUG: Some types of files are not closed after processing

The file is not closed after multi-page or tiled images are
processed. This results in unclosed file descriptors. Some systems
have limits on the number of open file descriptors. If a large number
of files are processed, subsequent open's may fail even if the file
exists.

Added a test to check if multiple reads do not fail.

Change-Id: I8e97496aae32bc8249b5b26a6101c81d6829ed1b
parent 46e6c6fe
......@@ -13,6 +13,15 @@ vtk_add_test_cxx(${vtk-module}CxxTests tests
TestImportExport.cxx
)
# Each of these most be added in a separate vtk_add_test_cxx
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestTIFFReaderMultipleMulti,TestTIFFReaderMultiple.cxx,NO_VALID,NO_OUTPUT
"DATA{${VTK_TEST_INPUT_DIR}/libtiff/multipage_tiff_example.tif}")
vtk_add_test_cxx(${vtk-module}CxxTests tests
TestTIFFReaderMultipleNormal,TestTIFFReaderMultiple.cxx,NO_VALID,NO_OUTPUT
"DATA{${VTK_TEST_INPUT_DIR}/libtiff/test.tif}")
set(all_tests
${data_tests}
${tests}
......
/*=========================================================================
Program: Visualization Toolkit
Module: TestTIFFReaderMultiple.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include <vtkTIFFReader.h>
#include <vtkSmartPointer.h>
#include "vtkTestErrorObserver.h"
#ifndef _WIN32
#include <sys/resource.h>
#endif
int TestTIFFReaderMultiple(int argc, char *argv[])
{
if ( argc <= 1 )
{
std::cout << "Usage: " << argv[0] << " <meta image file>" << endl;
return EXIT_FAILURE;
}
#ifndef _WIN32
// Set the limit on the number of open files
struct rlimit rl;
rl.rlim_cur = 9;
rl.rlim_max = 10;
setrlimit(RLIMIT_NOFILE, &rl);
#endif
vtkSmartPointer<vtkTest::ErrorObserver> errorObserver =
vtkSmartPointer<vtkTest::ErrorObserver>::New();
// Read the same file multiple times to check for memory leaks and/or
// file descriptor leaks
for (int i = 0; i < 9; i++)
{
vtkSmartPointer<vtkTIFFReader> TIFFReader =
vtkSmartPointer<vtkTIFFReader>::New();
TIFFReader->AddObserver(vtkCommand::ErrorEvent,errorObserver);
TIFFReader->SetFileName(argv[1]);
TIFFReader->Update();
std::cout << i << std::endl;
if (errorObserver->GetError())
{
std::cout << "ERROR: " << errorObserver->GetErrorMessage() << std::endl;
return EXIT_FAILURE;
}
errorObserver->Clear();
}
return EXIT_SUCCESS;
}
......@@ -20,6 +20,8 @@
#include "vtkErrorCode.h"
#include "vtkObjectFactory.h"
#include "vtksys/SystemTools.hxx"
#include <sys/stat.h>
#include <string>
......@@ -389,7 +391,10 @@ void vtkTIFFReader::ExecuteInformation()
if (!this->InternalImage->Open(this->InternalFileName))
{
vtkErrorMacro("Unable to open file " << this->InternalFileName);
vtkErrorMacro("Unable to open file "
<< this->InternalFileName
<< " Reason: "
<< vtksys::SystemTools::GetLastSystemError());
this->SetErrorCode(vtkErrorCode::CannotOpenFileError);
this->DataExtent[0] = 0;
this->DataExtent[1] = 0;
......@@ -599,8 +604,6 @@ void vtkTIFFReader::Process2(OT *outPtr, int *)
this->Initialize();
this->ReadImageInternal(outPtr);
// Close the file
this->InternalImage->Clean();
}
//----------------------------------------------------------------------------
......@@ -613,6 +616,8 @@ void vtkTIFFReader::Process(OT *outPtr, int outExtent[6], vtkIdType outIncr[3])
if (this->InternalImage->NumberOfPages > 1)
{
this->ReadVolume(outPtr);
// close the TIFF file
this->InternalImage->Clean();
return;
}
......@@ -620,6 +625,8 @@ void vtkTIFFReader::Process(OT *outPtr, int outExtent[6], vtkIdType outIncr[3])
if (this->InternalImage->NumberOfTiles > 0)
{
this->ReadTiles(outPtr);
// close the TIFF file
this->InternalImage->Clean();
return;
}
......@@ -634,6 +641,9 @@ void vtkTIFFReader::Process(OT *outPtr, int outExtent[6], vtkIdType outIncr[3])
this->ComputeInternalFileName(idx2);
// read in a TIFF file
this->Process2(outPtr2, outExtent);
// close the TIFF file
this->InternalImage->Clean();
this->UpdateProgress((idx2 - outExtent[4])/
(outExtent[5] - outExtent[4] + 1.0));
outPtr2 += outIncr[2];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment