Skip to content

Commit

Permalink
param: exec: rewrite exec
Browse files Browse the repository at this point in the history
This rewrites the exec function to have a persistent
shell. This should reduce or even fix frame time spikes
when updating outputs
  • Loading branch information
flightlessmango committed Apr 4, 2024
1 parent bdd2a02 commit 3c743a9
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 2 deletions.
5 changes: 4 additions & 1 deletion src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1658,8 +1658,11 @@ void HudElements::legacy_elements(){
}

void HudElements::update_exec(){
if (!HUDElements.shell)
HUDElements.shell = std::make_unique<Shell>();

for(auto& item : exec_list)
item.ret = exec(item.value);
item.ret = HUDElements.shell->exec(item.value + "\n");
}

HudElements HUDElements;
2 changes: 2 additions & 0 deletions src/hud_elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <array>
#include "net.h"
#include "overlay_params.h"
#include "shell.h"

struct Function {
std::function<void()> run; // Using std::function instead of a raw function pointer for more flexibility
Expand Down Expand Up @@ -53,6 +54,7 @@ class HudElements{
int refresh = 0;
std::unique_ptr<WineSync> winesync_ptr = nullptr;
std::unique_ptr<Net> net = nullptr;
std::unique_ptr<Shell> shell = nullptr;

void sort_elements(const std::pair<std::string, std::string>& option);
void legacy_elements();
Expand Down
3 changes: 2 additions & 1 deletion src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ if is_unixy
'amdgpu.cpp',
'intel.cpp',
'msm.cpp',
'net.cpp'
'net.cpp',
'shell.cpp'
)

opengl_files = files(
Expand Down
73 changes: 73 additions & 0 deletions src/shell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include "shell.h"
#include <thread>
#include <iostream>
#include <sys/wait.h>

std::string Shell::readOutput() {
std::string output;
char buffer[256];
ssize_t bytesRead;
bool dataAvailable = false;

// Wait for up to 500 milliseconds for output to become available
for (int i = 0; i < 10; ++i) {
bytesRead = read(from_shell[0], buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
output += buffer;
dataAvailable = true;
break; // Break as soon as we get some data
} else {
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}

// If we detected data, keep reading until no more is available
while (dataAvailable) {
bytesRead = read(from_shell[0], buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = '\0';
output += buffer;
} else {
break; // No more data available
}
}

return output;
}

Shell::Shell() {
pipe(to_shell);
pipe(from_shell);

shell_pid = fork();

if (shell_pid == 0) { // Child process
close(to_shell[1]);
close(from_shell[0]);

dup2(to_shell[0], STDIN_FILENO);
dup2(from_shell[1], STDOUT_FILENO);
dup2(from_shell[1], STDERR_FILENO);
execl("/bin/sh", "sh", nullptr);
exit(1); // Exit if execl fails
} else {
close(to_shell[0]);
close(from_shell[1]);

// Set the read end of the from_shell pipe to non-blocking
setNonBlocking(from_shell[0]);
}
}

std::string Shell::exec(std::string cmd) {
writeCommand(cmd);
return readOutput();
}

Shell::~Shell() {
write(to_shell[1], "exit\n", 5);
close(to_shell[1]);
close(from_shell[0]);
waitpid(shell_pid, nullptr, 0);
}
33 changes: 33 additions & 0 deletions src/shell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once
#include <fcntl.h>
#include <unistd.h>
#include <cstring>
#include <sys/wait.h>
#include <string>
#include <memory>

class Shell {
private:
int to_shell[2];
int from_shell[2];
pid_t shell_pid;

void setNonBlocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

void writeCommand(const std::string& command) {
write(to_shell[1], command.c_str(), command.length());
}

std::string readOutput();

public:
Shell();
~Shell();
std::string exec(std::string cmd);

};

extern std::unique_ptr<Shell> shell;

0 comments on commit 3c743a9

Please sign in to comment.