-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathr2pipe_impl.h
More file actions
70 lines (54 loc) · 1.5 KB
/
r2pipe_impl.h
File metadata and controls
70 lines (54 loc) · 1.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#pragma once
#include "include/common.h"
#include "include/subprocess.h"
#include "r2pipe.h"
#include <deque>
#include <condition_variable>
#include <stop_token> // C++20
#include <chrono>
class RingBuffer {
public:
void push(std::string_view data);
/*
可以用于清空缓冲区.
*/
vector<char> pop_all();
/*
非阻塞版本. 未找到分隔符, 则直接退出.
执行命令后, 可能 stdout 未完全输出, 这时用该函数可能会失败.
*/
vector<char> pop_until_nonblock(char delimiter);
/*
阻塞版本. 可能导致阻塞. 遇到 delimiter / EOF 返回.
注意, 返回的结果包含分隔符. 如果分隔符是 \0, 则可以视作字符串.
*/
vector<char> pop_until(char delimiter);
void set_eof();
private:
std::deque<char> buffer_;
bool eof = false;
std::mutex mutex_;
std::condition_variable not_empty_;
};
/*
Process 类的具体细节
*/
struct Process::Impl {
subprocess_s process{};
std::jthread reader_thread;
RingBuffer buffer;
explicit Impl(ArgvT args);
~Impl();
int join();
int terminate();
bool is_alive();
std::vector<char> read_all();
std::vector<char> read_until(char delimiter);
std::vector<char> read_until_nonblock(char delimiter);
void write(std::span<const char> data);
static bool in_path(ArgvT exe);
private:
void start_reader_thread();
void create_subprocess(const std::vector<const char*>& args);
static std::vector<const char*> make_argv(ArgvT args);
};