Commit d542d430 authored by Paal Kvamme's avatar Paal Kvamme
Browse files

New zgycopyc option to explicitly ignore or report SIGPIPE. Partial workaround...

New zgycopyc option to explicitly ignore or report SIGPIPE. Partial workaround for an issue possibly in Azure SDK and/or SSL.
parent dbfdac1e
......@@ -38,6 +38,9 @@
#include <omp.h>
#include <atomic>
#include <cstring>
#ifndef _WIN32
#include <signal.h>
#endif
#ifndef _WIN32
#include <unistd.h>
......@@ -89,6 +92,7 @@ public:
bool alpha; // Still unused.
bool dumpsqnr; // Still unused.
bool native;
std::string sigpipe;
std::string input;
std::string output;
std::array<std::int64_t,4> fakesize;
......@@ -108,6 +112,7 @@ public:
, alpha(false)
, dumpsqnr(false)
, native(true)
, sigpipe()
, input()
, output()
, fakesize(std::array<std::int64_t,4>{0,0,0,0})
......@@ -147,6 +152,7 @@ public:
//"-D, --dumpsqnr: *Dump table of sqnr vs. compression ratio.",
"-N, --native: Read/write as file's type (default).",
"-F, --float: Read/write as float.",
"-p, --sigpipe SIGPIPE disposition.",
"-i, --input FILE.zgy: Input file name. If missing, use random data.",
"-o, --output FILE.zgy: Output file name. If missing, discard data.",
"-s, --size I,J,K,S: Size, if no input file. E.g. 16x16x16x2.",
......@@ -174,7 +180,8 @@ public:
<< (randomize ? "--randomize " : "")
<< (alpha ? "--alpha " : "")
<< (dumpsqnr ? "--dumpsqnr " : "")
<< (native ? "--native " : "--float");
<< (native ? "--native " : "--float ")
<< (sigpipe.empty() ? "" : ("--sigpipe " + sigpipe + " "));
if (fakesize[0]||fakesize[1]||fakesize[2]||fakesize[3])
os << "--size "
......@@ -305,7 +312,7 @@ public:
static const char* short_options()
{
return "hvqGuraDNFi:o:s:l:b:B:g:t:n:Q:";
return "hvqGuraDNFp:i:o:s:l:b:B:g:t:n:Q:";
}
static const struct option *long_options()
......@@ -321,6 +328,7 @@ public:
{"dumpsqnr", no_argument, 0, 'D' },
{"native", no_argument, 0, 'N' },
{"float", no_argument, 0, 'F' },
{"sigpipe", required_argument, 0, 'p' },
{"input", required_argument, 0, 'i' },
{"output", required_argument, 0, 'o' },
{"size", required_argument, 0, 's' },
......@@ -354,6 +362,7 @@ public:
case 'D': throw std::runtime_error("--dumpsqnr not supported"); //dumpsqnr = true; break;
case 'N': native = true; break;
case 'F': native = false; break;
case 'p': sigpipe = optarg; break;
case 'i':
if (fakesize[0]||fakesize[1]||fakesize[2]||fakesize[3])
......@@ -633,7 +642,7 @@ suggestRange(float value, OpenZGY::SampleDataType dt, float *lo, float *hi)
}
void
copy(const Options& opt, SummaryTimer& rtimer, SummaryTimer& wtimer, SummaryTimer& rwtimer, SummaryTimer& ftimer)
copy(const Options& opt, SummaryPrintingTimer& rtimer, SummaryPrintingTimer& wtimer, SummaryPrintingTimer& rwtimer, SummaryPrintingTimer& ftimer)
{
using namespace OpenZGY;
ProgressWithDots p1, p2;
......@@ -791,6 +800,8 @@ copy(const Options& opt, SummaryTimer& rtimer, SummaryTimer& wtimer, SummaryTime
}
try {
copychunk(r, w, tasklist[task], bs, surveysize, buf.get(), dt, rtimer, wtimer);
//char c = '0' + omp_get_thread_num();
//::write(2, &c, 1);
}
catch (const std::exception& ex) {
if (errors.fetch_add(1) == 0)
......@@ -814,6 +825,14 @@ copy(const Options& opt, SummaryTimer& rtimer, SummaryTimer& wtimer, SummaryTime
throw std::runtime_error(first_error);
}
// In case finalize or close hangs or crashes, output the timing results
// now instead of having them printed automatically in main(). If the code
// threw an exception we won't get here. But in that case the normal
// mechanism of printing from the timer's destructor is invoked.
rtimer.print();
wtimer.print();
rwtimer.print();
SimpleTimer ft(ftimer);
if (opt.nolod) {
w->close_incomplete();
......@@ -822,12 +841,75 @@ copy(const Options& opt, SummaryTimer& rtimer, SummaryTimer& wtimer, SummaryTime
w->finalize(opt.algorithm, std::ref(p2));
w->close();
}
ftimer.print();
}
#ifndef _WIN32
void sigpipe_report(int)
{
static const char* msg = "WARNING: caught a SIGPIPE\n";
write(2, msg, strlen(msg));
}
void sigpipe_fatal(int)
{
static const char* msg = "FATAL: caught a SIGPIPE\n";
write(2, msg, strlen(msg));
_exit(3);
}
void signals(const Options& opt)
{
if (opt.sigpipe.empty()) {
// SIG_DFL or SIG_IGN inherited from parent
}
else if (opt.sigpipe == "inherit") {
// SIG_DFL or SIG_IGN inherited from parent
}
else if (opt.sigpipe == "ignore") {
::signal(SIGPIPE, SIG_IGN);
}
else if (opt.sigpipe == "default") {
::signal(SIGPIPE, SIG_DFL);
}
else if (opt.sigpipe == "report") {
struct sigaction act{0};
act.sa_handler = sigpipe_report;
::sigaction(SIGPIPE, &act, NULL);
}
else if (opt.sigpipe == "fatal") {
struct sigaction act{0};
act.sa_handler = sigpipe_fatal;
::sigaction(SIGPIPE, &act, NULL);
}
else {
std::cerr << "Allowable values for --sigpipe:\n"
<< " inherit | ignore | default | report | fatal\n"
<< std::flush;
throw std::runtime_error("Invalid argument to --sigpipe");
}
}
#else
void signals(const Options& opt)
{
// Signals might actually work on Windows but I don't have time
// to test that now. And yagni unless SIGPIPE problems start
// popping up on Windows as well.
if (!opt.sigpipe.empty()) {
throw std::runtime_error("The --signal option is not supported on Windows");
}
}
#endif
int main(int argc, char **argv)
{
try {
Options options(argc, argv);
signals(options);
SummaryPrintingTimer stimer("sync");
SummaryPrintingTimer ftimer("finalize");
SummaryPrintingTimer rwtimer("read+write");
......@@ -840,6 +922,7 @@ int main(int argc, char **argv)
SimpleTimer stim(stimer);
sync();
}
stimer.print();
#endif
}
catch (const std::exception& ex) {
......@@ -849,4 +932,8 @@ int main(int argc, char **argv)
std::cerr << myname << ": " << ex.what() << std::endl;
exit(1);
}
std::cerr << std::flush;
std::cout << std::flush;
std::cout << "Ok, normal termination of zgycopy." << std::endl;
exit(0);
}
Supports Markdown
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