[cig-commits] commit 1953 by bangerth to /var/svn/dealii/aspect
dealii.demon at gmail.com
dealii.demon at gmail.com
Mon Oct 14 07:45:32 PDT 2013
Revision 1953
Rewrite the code for first writing into a file in /tmp and then moving it into the final location. Allow failure first with retries.
U trunk/aspect/source/postprocess/visualization.cc
http://www.dealii.org/websvn/revision.php?repname=Aspect+Repository&path=%2F&rev=1953&peg=1953
Diff:
Modified: trunk/aspect/source/postprocess/visualization.cc
===================================================================
--- trunk/aspect/source/postprocess/visualization.cc 2013-10-14 14:08:00 UTC (rev 1952)
+++ trunk/aspect/source/postprocess/visualization.cc 2013-10-14 14:45:21 UTC (rev 1953)
@@ -33,6 +33,7 @@
#include <math.h>
#include <stdio.h>
+#include <unistd.h>
namespace aspect
{
@@ -426,65 +427,92 @@
{
// write stuff into a (hopefully local) tmp file first. to do so first
// find out whether $TMPDIR is set and if so put the file in there
- char tmp_filename[1025], *tmp_filedir;
- int tmp_file_desc;
- FILE *out_fp;
- static bool wrote_warning = false;
- bool using_bg_tmp = true;
+ std::string tmp_filename;
{
// Try getting the environment variable for the temporary directory
- tmp_filedir = getenv("TMPDIR");
+ const char *tmp_filedir = getenv("TMPDIR");
// If we can't, default to /tmp
- sprintf(tmp_filename, "%s/tmp.XXXXXX", (tmp_filedir?tmp_filedir:"/tmp"));
- // Create the temporary file
- tmp_file_desc = mkstemp(tmp_filename);
+ if (tmp_filedir)
+ tmp_filename = tmp_filedir;
+ else
+ tmp_filename = "/tmp";
+ tmp_filename += "/aspect.tmp.XXXXXX";
+ // Create the temporary file; get at the actual filename
+ // by using a C-style string that mkstemp will then overwrite
+ char *tmp_filename_x = new char[tmp_filename.size()+1];
+ std::strcpy(tmp_filename_x, tmp_filename.c_str());
+ const int tmp_file_desc = mkstemp(tmp_filename_x);
+ tmp_filename = tmp_filename_x;
+ delete tmp_filename_x;
+
// If we failed to create the temp file, just write directly to the target file
if (tmp_file_desc == -1)
{
- if (!wrote_warning)
- std::cerr << "***** WARNING: could not create temporary file, will "
+ std::cerr << "***** WARNING: could not create temporary file, will "
"output directly to final location. This may negatively "
- "affect performance." << std::endl;
- wrote_warning = true;
+ "affect performance."
+ " (On processor "
+ << Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) << ".)"
+ << std::endl;
- // Set the filename to be the specified input name
- sprintf(tmp_filename, "%s", filename->c_str());
- out_fp = fopen(tmp_filename, "w");
- using_bg_tmp = false;
+ tmp_filename = *filename;
}
- else
- {
- out_fp = fdopen(tmp_file_desc, "w");
- }
}
- // write the data into the file
- {
- if (!out_fp)
- {
- std::cerr << "***** ERROR: could not create " << tmp_filename
- << " *****"
- << std::endl;
- }
- else
- {
- fprintf(out_fp, "%s", file_contents->c_str());
- fclose(out_fp);
- }
- }
+ // open the file. if we can't open it, abort if this is the "real"
+ // file. re-try with the "real" file if we had tried to write to
+ // a temporary file
+ re_try_with_non_tmp_file:
+ std::cout << "********************** Writing to " << tmp_filename << std::endl;
+ std::ofstream out (tmp_filename.c_str());
+ if (!out)
+ {
+ if (tmp_filename == *filename)
+ AssertThrow (false, ExcMessage(std::string("Trying to write to file <") +
+ *filename +
+ " but the file can't be opened!"))
+ else
+ {
+ tmp_filename = *filename;
+ goto re_try_with_non_tmp_file;
+ }
+ }
- if (using_bg_tmp)
+ // now write and then move the tmp file to its final destination
+ // if necessary
+ out << file_contents;
+
+ if (tmp_filename != *filename)
{
- // now move the file to its final destination on the global file system
std::string command = std::string("mv ") + tmp_filename + " " + *filename;
+
+ bool first_attempt = true;
+
+ re_try:
int error = system(command.c_str());
+
+ // if the move failed, and this is the first time, sleep for a second in
+ // hopes that it was just an NFS timeout, then try again. if it fails the
+ // second time around, try writing to the final file directly.
if (error != 0)
+ if (first_attempt == true)
+ {
+ first_attempt = false;
+ sleep (1);
+ goto re_try;
+ }
+ else
{
- std::cerr << "***** ERROR: could not move " << tmp_filename
- << " to " << *filename << " *****"
+ std::cerr << "***** WARNING: could not move " << tmp_filename
+ << " to " << *filename << ". Trying again to write directly to "
+ << *filename
+ << ". (On processor "
+ << Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) << ".)"
<< std::endl;
+ tmp_filename = *filename;
+ goto re_try_with_non_tmp_file;
}
}
More information about the CIG-COMMITS
mailing list