Skip to content
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

Fifo debug #3

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
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
55 changes: 54 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,56 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
"typescript.tsdk": "node_modules/typescript/lib",
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"ratio": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"typeinfo": "cpp"
}
}
124 changes: 122 additions & 2 deletions runner/addon/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <uv.h>
// #include <iostream>


#include "ev_loop.h"
// #include "childsub_cb.h"
#include "childsub.h"
Expand All @@ -26,23 +25,59 @@ using namespace Napi;
Value fork_fn(const CallbackInfo &info)
{
int id = info[0].As<Number>();
int closeFd = info[1].As<Number>();
// Function callback = info[1].As<Function>();
// SimpleAsyncWorker* asyncWorker = new SimpleAsyncWorker(callback, runTime);
// asyncWorker->Queue();
// std::string msg =
// "SimpleAsyncWorker for " + std::to_string(runTime) + " seconds queued.";
// return String::New(info.Env(), msg.c_str());
int err;
ssize_t r;
int exec_errorno;

int signal_pipe[2] = {-1, -1};

err = uv_pipe(signal_pipe, 0, 0);
if (err)
throw std::runtime_error("fork failed");

pid_t pid = fork();

if (pid < 0)
{
close(signal_pipe[0]);
throw std::runtime_error("fork failed");
}

if (pid == 0)
{ // im children
// setsid(); 30 s faster??
close(closeFd);
int fd0 = open("/dev/null", O_RDONLY);
int fd1 = open("/dev/null", O_RDWR);
int fd2 = open("/dev/null", O_RDWR);
if (fd0 < 0)
{
perror("open failed\n");
exit(0);
}
if (fd1 < 0)
{
perror("open failed\n");
exit(0);
}
if (fd2 < 0)
{
perror("open failed\n");
exit(0);
}
dup2(fd0, 0);
close(fd0);
// dup2(fd1, 1);
close(fd1);
// dup2(fd2, 2);
close(fd2);
// setsid(); // 30 s faster??
uv_loop_t *loop;
if (napi_get_uv_event_loop(info.Env(), &loop))
{
Expand All @@ -52,9 +87,17 @@ Value fork_fn(const CallbackInfo &info)
// auto loop = uv_default_loop();

uv_loop_fork(loop);
write(signal_pipe[1], 0, sizeof 0);
close(signal_pipe[1]);
}
else
{
close(signal_pipe[1]);

do
r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno));
while (r == -1 && errno == EINTR);

// im parent
write_proc_data(ProcMsgTypes::created, pid, id);
}
Expand All @@ -65,6 +108,9 @@ Value fork_fn(const CallbackInfo &info)
// }

return Number::New(info.Env(), pid);

// error:
// throw std::runtime_error("fork failed");
};

Value get_my_pid(const CallbackInfo &info)
Expand Down Expand Up @@ -104,6 +150,73 @@ void send_this_proc_ok(const CallbackInfo &info)
write_proc_data(ProcMsgTypes::proc_ok, getpid(), 0);
}

void close_fd(const CallbackInfo &info)
{
int fd = info[0].As<Number>();
close(fd);
}

Value pipefd(const CallbackInfo &info)
{
int fd1[2];
if (pipe(fd1) == -1)
{
throw std::runtime_error("pipe failed");
}
Object obj = Object::New(info.Env());
obj.Set("read", fd1[0]);
obj.Set("write", fd1[1]);
return obj;
}

void on_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf)
{
if (nread < 0)
{
if (nread != UV_EOF)
fprintf(stderr, "Read error %s\n", uv_err_name(nread));
uv_close((uv_handle_t *)client, NULL);
free(buf->base);
return;
}

char *data = (char *)malloc(sizeof(char) * (nread + 1));
data[nread] = '\0';
strncpy(data, buf->base, nread);

fprintf(stdout, "%s", data);
free(data);
free(buf->base);
}

void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
{
*buf = uv_buf_init((char *)malloc(suggested_size), suggested_size);
}

void sub_pipe(const CallbackInfo &info)
{
int fd1 = info[0].As<Number>();
// int fd2 = info[1].As<Number>();
uv_loop_t *loop;
if (napi_get_uv_event_loop(info.Env(), &loop))
{
throw std::runtime_error("get loop failed");
};
uv_pipe_t *pipe = (uv_pipe_t *)malloc(sizeof(uv_pipe_t));

uv_pipe_init(loop, pipe, true);
uv_pipe_open(pipe, fd1);
// uv_pipe_connect()
int r;
if ((r = uv_read_start((uv_stream_t *)pipe, alloc_buffer, on_read)))
{
fprintf(stderr, "%s\n", uv_strerror(r));
throw std::runtime_error("uv_read_start failed");
}
return;
}

Object Init(Env env, Object exports)
{
exports["fork"] = Function::New(
Expand All @@ -112,12 +225,19 @@ Object Init(Env env, Object exports)
env, get_my_pid, std::string("get_my_pid"));
exports["subscribe_child"] = Function::New(
env, subscribe_child, std::string("subscribe_child"));
exports["close"] = Function::New(
env, close_fd, std::string("close"));
exports["make_fifo"] = Function::New(
env, make_fifo, std::string("make_fifo"));
exports["send_this_proc_ok"] = Function::New(
env, send_this_proc_ok, std::string("send_this_proc_ok"));
exports["wait_for_all_children"] = Function::New(
env, wait_for_all_children, std::string("wait_for_all_children"));
exports["pipe"] = Function::New(
env, pipefd, std::string("pipe"));

exports["sub_pipe"] = Function::New(
env, sub_pipe, std::string("sub_pipe"));
return exports;
}

Expand Down
12 changes: 7 additions & 5 deletions runner/addon/childsub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ int write_proc_data(int arg1, int arg2, int arg3)
{
data[i] = htonl(data[i]);
}
int written = write(fd, data, SIZE_BYTES);
if (written<0) {
throw std::runtime_error("write to fifo failed");
}
return written;
// int written = write(fd, data, SIZE_BYTES);
// if (written<0) {
// throw std::runtime_error("write to fifo failed");
// }
return 0;
// return written;
}

void child_handler(int sign)
Expand All @@ -60,6 +61,7 @@ void child_handler(int sign)

void subscribe_child(const CallbackInfo &info)
{
return;
if (sub_called) {
throw std::runtime_error("subscribe_child can only be called once");
}
Expand Down
1 change: 1 addition & 0 deletions runner/addon/childsub_cb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ void signal_handler(uv_signal_t *handle, int signum)

Value subscribe_child(const CallbackInfo &info)
{
return;
// // using namespace std::placeholders;
Function callback = info[0].As<Function>();

Expand Down
26 changes: 19 additions & 7 deletions runner/src/addon.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const bindings = require('../build/Release/addon');
const inspector = require('inspector') as typeof import('inspector');

function fork(id: number): number {

function fork(id: number, closeFd: number): number {
// inspector.close()
const pid = bindings.fork(id);
const pid = bindings.fork(id,closeFd);
if(pid === 0) { //children
// inspector.close()
// inspector.Session
Expand All @@ -29,15 +29,27 @@ function make_fifo(path: string) {
}

function startProcControl(path: string) {
bindings.subscribe_child(path)
// bindings.subscribe_child(path)
}

function sendThisProcOk() {
bindings.send_this_proc_ok()
// bindings.send_this_proc_ok()
}

function waitForAllChildren(){
bindings.wait_for_all_children()
// bindings.wait_for_all_children()
}

function close(fd: number) {
return bindings.close(fd)
}

function sub_pipe(fd: number) {
return bindings.sub_pipe(fd)
}

function pipe(): {read: number, write: number} {
return bindings.pipe()
}

export {fork, startProcControl, make_fifo, sendThisProcOk, waitForAllChildren}
export {fork, close, startProcControl, make_fifo, sendThisProcOk, waitForAllChildren, pipe, sub_pipe}
2 changes: 2 additions & 0 deletions runner/src/fifo-maker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import * as addon from './addon';
export interface Fifo {
path: string;
id: number;
pipe?: {read: number, write: number}
}

export class FifoMaker {
Expand All @@ -22,6 +23,7 @@ export class FifoMaker {

makeFifo(desc: string): Fifo {
const id = this.curId++;
console.error('fifo', desc, id)
const p = path.join(this.baseDir, `pipe_${desc}_${id}`);
addon.make_fifo(p);
const fifo: Fifo = {path: p, id};
Expand Down
Loading