Skip to content

Better nob_procs_append_with_flush #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions nob.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
# include <sys/stat.h>
# include <unistd.h>
# include <fcntl.h>
# include <signal.h>
#endif

#ifdef _WIN32
Expand Down Expand Up @@ -400,7 +401,9 @@ bool nob_proc_wait(Nob_Proc proc);
bool nob_procs_wait(Nob_Procs procs);
// Wait until all the processes have finished and empty the procs array
bool nob_procs_wait_and_reset(Nob_Procs *procs);
// Append a new process to procs array and if procs.count reaches max_procs_count call nob_procs_wait_and_reset() on it
// Flush finished processes from the procs array
bool nob_procs_flush(Nob_Procs *procs);
// Append a new process to procs array and if procs.count reaches max_procs_count call nob_procs_flush() until it is below max_procs_count again
bool nob_procs_append_with_flush(Nob_Procs *procs, Nob_Proc proc, size_t max_procs_count);

// A command - the main workhorse of Nob. Nob is all about building commands an running them
Expand Down Expand Up @@ -1034,6 +1037,7 @@ void nob_fd_close(Nob_Fd fd)

bool nob_procs_wait(Nob_Procs procs)
{
nob_procs_flush(&procs);
bool success = true;
for (size_t i = 0; i < procs.count; ++i) {
success = nob_proc_wait(procs.items[i]) && success;
Expand Down Expand Up @@ -1105,12 +1109,67 @@ bool nob_proc_wait(Nob_Proc proc)
#endif
}

bool nob_procs_flush(Nob_Procs *procs)
{
bool success = true;

Nob_Procs new_procs = {0};

for (size_t i = procs->count; i > 0; i--) {
Nob_Proc proc = procs->items[i - 1];
#ifdef _WIN32
DWORD result = WaitForSingleObject(
proc, // HANDLE hHandle,
0 // DWORD dwMilliseconds
);

if (result == WAIT_FAILED) {
nob_log(NOB_ERROR, "could not wait on child process: %s", nob_win32_error_message(GetLastError()));
return false;
}

if (result == WAIT_TIMEOUT) {
nob_da_append(&new_procs, proc);
continue;
}

DWORD exit_status;
if (!GetExitCodeProcess(proc, &exit_status)) {
nob_log(NOB_ERROR, "could not get process exit code: %s", nob_win32_error_message(GetLastError()));
success = false;
continue;
}

if (exit_status != 0) {
nob_log(NOB_ERROR, "command exited with exit code %lu", exit_status);
success = false;
}

CloseHandle(proc);
#else
int status;
waitpid(proc, &status, WNOHANG);
if (kill(proc, 0) == -1) success = status == 0 && success;
else nob_da_append(&new_procs, proc);
#endif
}

if (procs->count != new_procs.count) {
NOB_FREE(procs->items);
*procs = new_procs;
} else {
nob_da_free(new_procs);
}

return success;
}

bool nob_procs_append_with_flush(Nob_Procs *procs, Nob_Proc proc, size_t max_procs_count)
{
nob_da_append(procs, proc);

if (procs->count >= max_procs_count) {
if (!nob_procs_wait_and_reset(procs)) return false;
while (procs->count >= max_procs_count) {
if (!nob_procs_flush(procs)) return false;
}

return true;
Expand Down