Wrap TEMP_FAILURE_RETRY around system calls
BUG 19934827
Wrap TEMP_FAILURE_RETRY around system calls that can return EINTR
(waitpid, close).
Refactor fork/exec flows in various places into a utility function
and log errors so we can better understand failures in the test server.
Fix a small use-after-free issue in ScriptGroups.
Change-Id: I60b192f83c395a13c27cd6bd2289c44132b84791
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 481c54d..6099cf4 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -23,6 +23,8 @@
#include <sys/stat.h>
#include <unistd.h>
#else
+ #include "rsCppUtils.h"
+
#include <bcc/BCCContext.h>
#include <bcc/Config/Config.h>
#include <bcc/Renderscript/RSCompilerDriver.h>
@@ -32,7 +34,6 @@
#include <zlib.h>
#include <sys/file.h>
#include <sys/types.h>
- #include <sys/wait.h>
#include <unistd.h>
#include <string>
@@ -122,8 +123,7 @@
static bool compileBitcode(const std::string &bcFileName,
const char *bitcode,
size_t bitcodeSize,
- const char **compileArguments,
- const char *compileCommandLine) {
+ std::vector<const char *> &compileArguments) {
rsAssert(bitcode && bitcodeSize);
FILE *bcfile = fopen(bcFileName.c_str(), "w");
@@ -139,39 +139,9 @@
return false;
}
- pid_t pid = fork();
-
- switch (pid) {
- case -1: { // Error occurred (we attempt no recovery)
- ALOGE("Couldn't fork for bcc compiler execution");
- return false;
- }
- case 0: { // Child process
- ALOGV("Invoking BCC with: %s", compileCommandLine);
- execv(android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH,
- (char* const*)compileArguments);
-
- ALOGE("execv() failed: %s", strerror(errno));
- abort();
- return false;
- }
- default: { // Parent process (actual driver)
- // Wait on child process to finish compiling the source.
- int status = 0;
- pid_t w = waitpid(pid, &status, 0);
- if (w == -1) {
- ALOGE("Could not wait for bcc compiler");
- return false;
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return true;
- }
-
- ALOGE("bcc compiler terminated unexpectedly");
- return false;
- }
- }
+ return android::renderscript::rsuExecuteCommand(
+ android::renderscript::RsdCpuScriptImpl::BCC_EXE_PATH,
+ compileArguments.size()-1, compileArguments.data());
}
bool isChecksumNeeded() {
@@ -200,7 +170,7 @@
break;
}
- if (close(FD) != 0) {
+ if (TEMP_FAILURE_RETRY(close(FD)) != 0) {
ALOGE("Cannot close file \'%s\' after computing checksum", fileName);
return false;
}
@@ -360,16 +330,17 @@
setCompileArguments(&compileArguments, bcFileName, cacheDir, resName, core_lib,
useRSDebugContext, bccPluginName);
- // The last argument of compileArguments is a nullptr, so remove 1 from the
- // size.
- std::unique_ptr<const char> compileCommandLine(
- rsuJoinStrings(compileArguments.size() - 1, compileArguments.data()));
-
mChecksumNeeded = isChecksumNeeded();
if (mChecksumNeeded) {
std::vector<const char *> bccFiles = { BCC_EXE_PATH,
core_lib,
};
+
+ // The last argument of compileArguments is a nullptr, so remove 1 from
+ // the size.
+ std::unique_ptr<const char> compileCommandLine(
+ rsuJoinStrings(compileArguments.size()-1, compileArguments.data()));
+
mBuildChecksum = constructBuildChecksum(bitcode, bitcodeSize,
compileCommandLine.get(),
bccFiles);
@@ -393,10 +364,6 @@
compileArguments.push_back(mBuildChecksum);
compileArguments.push_back(nullptr);
- // recompute compileCommandLine with the extra arguments
- compileCommandLine.reset(
- rsuJoinStrings(compileArguments.size() - 1, compileArguments.data()));
-
if (!is_force_recompile() && !useRSDebugContext) {
mScriptSO = SharedLibraryUtils::loadSharedLibrary(cacheDir, resName);
@@ -411,7 +378,7 @@
// again.
if (mScriptSO == nullptr) {
if (!compileBitcode(bcFileName, (const char*)bitcode, bitcodeSize,
- compileArguments.data(), compileCommandLine.get()))
+ compileArguments))
{
ALOGE("bcc: FAILS to compile '%s'", resName);
mCtx->unlockMutex();