Fixed issue where first process is null
This commit is contained in:
10
lbs.lua
10
lbs.lua
@@ -73,6 +73,10 @@ local function compile(CXX, src_dirs, include_dirs, defines, additional_argument
|
|||||||
local base_argv = {}
|
local base_argv = {}
|
||||||
|
|
||||||
additional_arguments[#additional_arguments+1] = "-c"
|
additional_arguments[#additional_arguments+1] = "-c"
|
||||||
|
if (config.buildmode == "debug") then
|
||||||
|
additional_arguments[#additional_arguments+1] = "-O0"
|
||||||
|
additional_arguments[#additional_arguments+1] = "-g"
|
||||||
|
end
|
||||||
for _,v in pairs(additional_arguments) do base_argv[#base_argv+1] = v end
|
for _,v in pairs(additional_arguments) do base_argv[#base_argv+1] = v end
|
||||||
for _,v in pairs(include_dirs) do base_argv[#base_argv+1] = "-I\"" .. v .. "\"" end
|
for _,v in pairs(include_dirs) do base_argv[#base_argv+1] = "-I\"" .. v .. "\"" end
|
||||||
for k,v in pairs(defines) do base_argv[#base_argv+1] = "-D" .. k .. "=" .. v end
|
for k,v in pairs(defines) do base_argv[#base_argv+1] = "-D" .. k .. "=" .. v end
|
||||||
@@ -100,6 +104,10 @@ end
|
|||||||
|
|
||||||
local function link(LNK, obj_dirs, library_dirs, linker_inputs, additional_arguments, file_output)
|
local function link(LNK, obj_dirs, library_dirs, linker_inputs, additional_arguments, file_output)
|
||||||
local argv = {}
|
local argv = {}
|
||||||
|
if (config.buildmode == "debug") then
|
||||||
|
additional_arguments[#additional_arguments+1] = "-O0"
|
||||||
|
additional_arguments[#additional_arguments+1] = "-g"
|
||||||
|
end
|
||||||
for _,v in pairs(library_dirs) do argv[#argv+1] = "-L\"" .. v .. "\"" end
|
for _,v in pairs(library_dirs) do argv[#argv+1] = "-L\"" .. v .. "\"" end
|
||||||
for _,v in pairs(linker_inputs) do argv[#argv+1] = "-l\"" .. v .. "\"" end
|
for _,v in pairs(linker_inputs) do argv[#argv+1] = "-l\"" .. v .. "\"" end
|
||||||
for _,v in pairs(additional_arguments) do argv[#argv+1] = v end
|
for _,v in pairs(additional_arguments) do argv[#argv+1] = v end
|
||||||
@@ -137,6 +145,8 @@ function build(...)
|
|||||||
compile(CXX, source_dirs, include_dirs, defines, additional_arguments)
|
compile(CXX, source_dirs, include_dirs, defines, additional_arguments)
|
||||||
|
|
||||||
link(CXX, {"obj"}, library_dirs, linker_inputs, {}, program_name)
|
link(CXX, {"obj"}, library_dirs, linker_inputs, {}, program_name)
|
||||||
|
|
||||||
|
print("Program generated! See " .. program_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
function main(...) build(...) end
|
function main(...) build(...) end
|
||||||
|
|||||||
@@ -106,11 +106,14 @@ int lua_fs_list_alldirs(lua_State* L)
|
|||||||
|
|
||||||
int lua_fs_foreach_dir(lua_State* L)
|
int lua_fs_foreach_dir(lua_State* L)
|
||||||
{
|
{
|
||||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
try {
|
||||||
const char* path = lua_tostring(L, 1);
|
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
||||||
|
const char* path = lua_tostring(L, 1);
|
||||||
|
|
||||||
void* ud = lua_newuserdata(L, sizeof(std::filesystem::directory_iterator));
|
void* ud = lua_newuserdata(L, sizeof(std::filesystem::directory_iterator));
|
||||||
new (ud) std::filesystem::directory_iterator(path);
|
new (ud) std::filesystem::directory_iterator(path);
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured creating fs.foreach iterator/generator\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
|
|
||||||
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.directory_iterator");
|
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
@@ -123,8 +126,11 @@ int lua_fs_forall_dir(lua_State* L)
|
|||||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
||||||
const char* path = lua_tostring(L, 1);
|
const char* path = lua_tostring(L, 1);
|
||||||
|
|
||||||
void* ud = lua_newuserdata(L, sizeof(std::filesystem::recursive_directory_iterator));
|
try {
|
||||||
new (ud) std::filesystem::recursive_directory_iterator(path);
|
void* ud = lua_newuserdata(L, sizeof(std::filesystem::recursive_directory_iterator));
|
||||||
|
new (ud) std::filesystem::recursive_directory_iterator(path);
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured creating fs.forall iterator/generator\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
|
|
||||||
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||||
lua_setmetatable(L, -2);
|
lua_setmetatable(L, -2);
|
||||||
@@ -134,51 +140,63 @@ int lua_fs_forall_dir(lua_State* L)
|
|||||||
|
|
||||||
int lua_fs_foreach_dir_next(lua_State* L)
|
int lua_fs_foreach_dir_next(lua_State* L)
|
||||||
{
|
{
|
||||||
int idx = lua_upvalueindex(1);
|
try {
|
||||||
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
int idx = lua_upvalueindex(1);
|
||||||
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.directory_iterator");
|
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
||||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||||
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
||||||
if (x._At_end())
|
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
||||||
return 0;
|
if (x._At_end())
|
||||||
std::string p = (*x).path().string();
|
return 0;
|
||||||
lua_pushlstring(L, p.c_str(), p.size());
|
std::string p = (*x).path().string();
|
||||||
x++;
|
lua_pushlstring(L, p.c_str(), p.size());
|
||||||
|
x++;
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured iterating fs.foreach\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_fs_forall_dir_next(lua_State* L)
|
int lua_fs_forall_dir_next(lua_State* L)
|
||||||
{
|
{
|
||||||
int idx = lua_upvalueindex(1);
|
try {
|
||||||
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
int idx = lua_upvalueindex(1);
|
||||||
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
||||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||||
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
||||||
if (x == std::filesystem::recursive_directory_iterator{})
|
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
||||||
return 0;
|
if (x == std::filesystem::recursive_directory_iterator{})
|
||||||
std::string p = (*x).path().string();
|
return 0;
|
||||||
lua_pushlstring(L, p.c_str(), p.size());
|
std::string p = (*x).path().string();
|
||||||
x++;
|
lua_pushlstring(L, p.c_str(), p.size());
|
||||||
|
x++;
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured iterating fs.forall\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_fs_foreach_dir_dtor(lua_State* L)
|
int lua_fs_foreach_dir_dtor(lua_State* L)
|
||||||
{
|
{
|
||||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
try {
|
||||||
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.directory_iterator");
|
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
||||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||||
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
||||||
x.~directory_iterator();
|
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
||||||
|
x.~directory_iterator();
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured destroying fs.foreach iterator/generator\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lua_fs_forall_dir_dtor(lua_State* L)
|
int lua_fs_forall_dir_dtor(lua_State* L)
|
||||||
{
|
{
|
||||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
try {
|
||||||
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
||||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||||
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
||||||
x.~recursive_directory_iterator();
|
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
||||||
|
x.~recursive_directory_iterator();
|
||||||
|
} catch (const std::exception& e)
|
||||||
|
{ return luaL_error(L, "%s:%d: An exception occured destroying fs.forall iterator/generator\n\t%s\n", __FUNCTION__, __LINE__, e.what()); }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,122 +65,151 @@ int lua_platform_exec(lua_State* L)
|
|||||||
|
|
||||||
int lua_platform_exec_parallel(lua_State* L)
|
int lua_platform_exec_parallel(lua_State* L)
|
||||||
{
|
{
|
||||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a command");
|
try {
|
||||||
luaL_argcheck(L, lua_type(L, 2) == LUA_TNUMBER, 2, "Expected second argument to be an integer representing the maximum number of parallel jobs to start");
|
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a command");
|
||||||
luaL_argcheck(L, lua_type(L, 3) == LUA_TTABLE, 3, "Expected third argument to be a table of table of strings representing the arguments");
|
luaL_argcheck(L, lua_type(L, 2) == LUA_TNUMBER, 2, "Expected second argument to be an integer representing the maximum number of parallel jobs to start");
|
||||||
const char* cmd = (lua_tostring(L, 1));
|
luaL_argcheck(L, lua_type(L, 3) == LUA_TTABLE, 3, "Expected third argument to be a table of table of strings representing the arguments");
|
||||||
const size_t max_parallel = lua_tointeger(L, 2);
|
const char* cmd = (lua_tostring(L, 1));
|
||||||
const size_t num_cmds = lua_objlen(L, 3);
|
const size_t max_parallel = lua_tointeger(L, 2);
|
||||||
|
const size_t num_cmds = lua_objlen(L, 3);
|
||||||
|
|
||||||
size_t* num_args = (size_t*)malloc(num_cmds * sizeof(size_t));
|
uniproc_process* workers = nullptr;
|
||||||
memset(num_args, 0, sizeof(size_t) * num_cmds);
|
int* retcodes = nullptr;
|
||||||
const char*** args = (const char***)malloc(num_cmds*sizeof(const char**));
|
size_t* num_args = nullptr;
|
||||||
|
const char*** args = nullptr;
|
||||||
// Generate the command stack from lua arguments
|
std::vector<std::string> std_outs;
|
||||||
for (size_t i = 0; i < num_cmds; ++i)
|
std::vector<std::string> std_errs;
|
||||||
{
|
|
||||||
lua_rawgeti(L, 3, i + 1);
|
try {
|
||||||
if (lua_istable(L, -1))
|
num_args = (size_t*)malloc(num_cmds * sizeof(size_t));
|
||||||
{
|
memset(num_args, 0, sizeof(size_t) * num_cmds);
|
||||||
const size_t tbl_num_args = lua_objlen(L, -1);
|
args = (const char***)malloc(num_cmds * sizeof(const char**));
|
||||||
num_args[i] = tbl_num_args;
|
|
||||||
args[i] = (const char**)malloc(tbl_num_args*sizeof(const char*));
|
// Generate the command stack from lua arguments
|
||||||
for (size_t j = 0; j < tbl_num_args; ++j)
|
for (size_t i = 0; i < num_cmds; ++i)
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, -1, j + 1);
|
lua_rawgeti(L, 3, i + 1);
|
||||||
if (!lua_isstring(L, -1))
|
if (lua_istable(L, -1))
|
||||||
return luaL_error(L, "Expected program argument to be a string. args[%d][%d] was a %s, not a string!\n", i, j, lua_typename(L, lua_type(L, -1)));
|
{
|
||||||
args[i][j] = lua_tostring(L, -1);
|
const size_t tbl_num_args = lua_objlen(L, -1);
|
||||||
|
num_args[i] = tbl_num_args;
|
||||||
|
args[i] = (const char**)malloc(tbl_num_args * sizeof(const char*));
|
||||||
|
for (size_t j = 0; j < tbl_num_args; ++j)
|
||||||
|
{
|
||||||
|
lua_rawgeti(L, -1, j + 1);
|
||||||
|
if (!lua_isstring(L, -1))
|
||||||
|
return luaL_error(L, "Expected program argument to be a string. args[%d][%d] was a %s, not a string!\n", i, j, lua_typename(L, lua_type(L, -1)));
|
||||||
|
args[i][j] = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lua_type(L, -1) == LUA_TSTRING)
|
||||||
|
{
|
||||||
|
num_args[i] = 1;
|
||||||
|
args[i] = (const char**)malloc(1 * sizeof(const char*));
|
||||||
|
args[i][0] = lua_tostring(L, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return luaL_error(L, "Expected a table of program arguments. args[%d] was a %s, not a table!\n", i, lua_typename(L, lua_type(L, -1)));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workers = (uniproc_process*)malloc(max_parallel * sizeof(uniproc_process));
|
||||||
|
uniproc_nullify_processes(workers, max_parallel);
|
||||||
|
retcodes = (int*)malloc(num_cmds * sizeof(int));
|
||||||
|
memset(retcodes, 0, num_cmds);
|
||||||
|
|
||||||
|
std_outs.resize(num_cmds, "");
|
||||||
|
std_errs.resize(num_cmds, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (lua_type(L, -1) == LUA_TSTRING)
|
catch (const std::exception& e) {
|
||||||
{
|
fprintf(stderr, "%s:%d: Exception occured in preparation for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
num_args[i] = 1;
|
return luaL_error(L, "%s:%d: Exception occured in preparation for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
args[i] = (const char**)malloc(1*sizeof(const char*));
|
|
||||||
args[i][0] = lua_tostring(L, -1);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return luaL_error(L, "Expected a table of program arguments. args[%d] was a %s, not a table!\n", i, lua_typename(L, lua_type(L, -1)));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uniproc_process* workers = (uniproc_process*)malloc(max_parallel*sizeof(uniproc_process));
|
size_t cmd_idx = 0;
|
||||||
uniproc_nullify_processes(workers, max_parallel);
|
while (cmd_idx < num_cmds || !uniproc_are_processes_finished(workers, max_parallel))
|
||||||
int* retcodes = (int*)malloc(num_cmds*sizeof(int));
|
|
||||||
memset(retcodes, 0, num_cmds);
|
|
||||||
|
|
||||||
std::vector<std::string> std_outs;
|
|
||||||
std::vector<std::string> std_errs;
|
|
||||||
std_outs.resize(num_cmds, "");
|
|
||||||
std_errs.resize(num_cmds, "");
|
|
||||||
|
|
||||||
|
|
||||||
size_t cmd_idx = 0;
|
|
||||||
while (cmd_idx < num_cmds || !uniproc_are_processes_finished(workers, max_parallel))
|
|
||||||
{
|
|
||||||
for (uniproc_process* p = workers; p != (workers + max_parallel); ++p)
|
|
||||||
{
|
{
|
||||||
// Check and handle a worker if it has completed
|
try {
|
||||||
if (uniproc_are_processes_finished(p, 1))
|
for (uniproc_process* p = workers; p != (workers + max_parallel); ++p)
|
||||||
{
|
|
||||||
char buf[64];
|
|
||||||
// Read the std. streams into the output vectors
|
|
||||||
while (fgets(buf, sizeof(buf), p->out) != NULL)
|
|
||||||
std_outs[p->userdata].append(buf);
|
|
||||||
while (fgets(buf, sizeof(buf), p->err) != NULL)
|
|
||||||
std_errs[p->userdata].append(buf);
|
|
||||||
// Add the process return code to retcode array
|
|
||||||
uniproc_await_processes(p, retcodes + p->userdata, 1);
|
|
||||||
// Close the process and zero it
|
|
||||||
uniproc_close_process(p);
|
|
||||||
}
|
|
||||||
// If a worker is null and there is more jobs to complete
|
|
||||||
// Create a new process
|
|
||||||
// Is a while loop to handle the possibility that process creation fails
|
|
||||||
while (uniproc_is_process_null(p) && cmd_idx < num_cmds)
|
|
||||||
{
|
|
||||||
// Create process
|
|
||||||
*p = uniproc_create_process(cmd, num_args[cmd_idx], args[cmd_idx]);
|
|
||||||
p->userdata = cmd_idx;
|
|
||||||
cmd_idx++;
|
|
||||||
|
|
||||||
// If we failed to create the process, set the output for it to an error value
|
|
||||||
if (uniproc_is_process_null(p))
|
|
||||||
{
|
{
|
||||||
std_outs[p->userdata] = "uniproc: failed to create process";
|
// Check and handle a worker if it has completed
|
||||||
std_errs[p->userdata] = "uniproc: failed to create process";
|
if (!uniproc_is_process_null(p) && uniproc_are_processes_finished(p, 1))
|
||||||
retcodes[p->userdata] = -1;
|
{
|
||||||
|
char buf[64];
|
||||||
|
// Read the std. streams into the output vectors
|
||||||
|
// TODO: Errors out here
|
||||||
|
fprintf(stderr, "p->out = %p\n", p->out);
|
||||||
|
while (fgets(buf, sizeof(buf), p->out) != NULL)
|
||||||
|
std_outs[p->userdata].append(buf);
|
||||||
|
fprintf(stderr, "C: %llu\n", cmd_idx);
|
||||||
|
fprintf(stderr, "p->err = %p\n", p->err);
|
||||||
|
while (fgets(buf, sizeof(buf), p->err) != NULL)
|
||||||
|
std_errs[p->userdata].append(buf);
|
||||||
|
fprintf(stderr, "D: %llu\n", cmd_idx);
|
||||||
|
// Add the process return code to retcode array
|
||||||
|
uniproc_await_processes(p, retcodes + p->userdata, 1);
|
||||||
|
// Close the process and zero it
|
||||||
|
uniproc_close_process(p);
|
||||||
|
}
|
||||||
|
// If a worker is null and there is more jobs to complete
|
||||||
|
// Create a new process
|
||||||
|
// Is a while loop to handle the possibility that process creation fails
|
||||||
|
while (uniproc_is_process_null(p) && cmd_idx < num_cmds)
|
||||||
|
{
|
||||||
|
// Create process
|
||||||
|
*p = uniproc_create_process(cmd, num_args[cmd_idx], args[cmd_idx]);
|
||||||
|
p->userdata = cmd_idx;
|
||||||
|
cmd_idx++;
|
||||||
|
|
||||||
|
// If we failed to create the process, set the output for it to an error value
|
||||||
|
if (uniproc_is_process_null(p))
|
||||||
|
{
|
||||||
|
std_outs[p->userdata] = "uniproc: failed to create process";
|
||||||
|
std_errs[p->userdata] = "uniproc: failed to create process";
|
||||||
|
retcodes[p->userdata] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// Await a process completing before trying to iterate again
|
||||||
|
// Prevents spinning the CPU
|
||||||
|
uniproc_await_any_processes(workers, max_parallel);
|
||||||
|
}
|
||||||
|
catch (const std::exception& e) {
|
||||||
|
fprintf(stderr, "%s:%d: Exception occured in parallel execution for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
|
return luaL_error(L, "%s:%d: Exception occured in parallel execution for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Await a process completing before trying to iterate again
|
|
||||||
// Prevents spinning the CPU
|
for (size_t i = 0; i < num_cmds; ++i)
|
||||||
uniproc_await_any_processes(workers, max_parallel);
|
free(args[i]);
|
||||||
|
free(num_args);
|
||||||
|
free(args);
|
||||||
|
// Don't need to close processes as that is handled in the command loop
|
||||||
|
free(workers);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Join thread results together and push them to lua stack
|
||||||
|
lua_newtable(L); // rc
|
||||||
|
lua_newtable(L); // stdout
|
||||||
|
lua_newtable(L); // stderr
|
||||||
|
for (size_t i = 0; i < num_cmds; ++i)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, retcodes[i]);
|
||||||
|
lua_rawseti(L, -4, i + 1);
|
||||||
|
lua_pushlstring(L, std_outs[i].c_str(), std_outs[i].size());
|
||||||
|
lua_rawseti(L, -3, i + 1);
|
||||||
|
lua_pushlstring(L, std_errs[i].c_str(), std_errs[i].size());
|
||||||
|
lua_rawseti(L, -2, i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
for (size_t i = 0; i < num_cmds; ++i)
|
|
||||||
free(args[i]);
|
|
||||||
free(num_args);
|
|
||||||
free(args);
|
|
||||||
// Don't need to close processes as that is handled in the command loop
|
|
||||||
free(workers);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Join thread results together and push them to lua stack
|
|
||||||
lua_newtable(L); // rc
|
|
||||||
lua_newtable(L); // stdout
|
|
||||||
lua_newtable(L); // stderr
|
|
||||||
for (size_t i = 0; i < num_cmds; ++i)
|
|
||||||
{
|
{
|
||||||
lua_pushinteger(L, retcodes[i]);
|
fprintf(stderr, "%s:%d: Exception occured in cleanup and result handling for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
lua_rawseti(L, -4, i+1);
|
return luaL_error(L, "%s:%d: Exception occured in cleanup and result handling for fs.parallel_exec(...)\n\t%s\n", __FUNCTION__, __LINE__, e.what());
|
||||||
lua_pushlstring(L, std_outs[i].c_str(), std_outs[i].size());
|
|
||||||
lua_rawseti(L, -3, i+1);
|
|
||||||
lua_pushlstring(L, std_errs[i].c_str(), std_errs[i].size());
|
|
||||||
lua_rawseti(L, -2, i+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
}
|
||||||
|
|||||||
2
thirdparty/luajit
vendored
2
thirdparty/luajit
vendored
Submodule thirdparty/luajit updated: a4f56a459a...84cb21ffaf
Reference in New Issue
Block a user