2023-10-31 19:28:40 +01:00
|
|
|
#include "pipe.hpp"
|
|
|
|
|
#include "error/ErrorCode.hpp"
|
|
|
|
|
#include "file.hpp"
|
2023-12-31 12:30:49 +01:00
|
|
|
#include "thread/Thread.hpp"
|
2023-10-31 19:28:40 +01:00
|
|
|
#include "uio.hpp"
|
2023-12-31 12:30:49 +01:00
|
|
|
#include "utils/Logs.hpp"
|
2023-10-31 19:28:40 +01:00
|
|
|
#include <span>
|
|
|
|
|
|
|
|
|
|
static orbis::ErrorCode pipe_read(orbis::File *file, orbis::Uio *uio,
|
|
|
|
|
orbis::Thread *thread) {
|
|
|
|
|
auto pipe = static_cast<orbis::Pipe *>(file);
|
|
|
|
|
while (true) {
|
|
|
|
|
if (pipe->data.empty()) {
|
2023-12-31 12:30:49 +01:00
|
|
|
// pipe->cv.wait(file->mtx);
|
|
|
|
|
// ORBIS_LOG_ERROR(__FUNCTION__, "wakeup", thread->name, thread->tid, file);
|
|
|
|
|
// continue;
|
|
|
|
|
return orbis::ErrorCode::WOULDBLOCK;
|
2023-10-31 19:28:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
|
|
|
|
|
auto size = std::min<std::size_t>(pipe->data.size(), vec.len);
|
2023-12-31 12:30:49 +01:00
|
|
|
|
|
|
|
|
if (size == 0) {
|
|
|
|
|
pipe->data.clear();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (size > pipe->data.size()) {
|
|
|
|
|
size = pipe->data.size();
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-31 19:28:40 +01:00
|
|
|
uio->offset += size;
|
|
|
|
|
std::memcpy(vec.base, pipe->data.data(), size);
|
|
|
|
|
|
2023-12-31 12:30:49 +01:00
|
|
|
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file, size, pipe->data.size(), uio->offset, file->nextOff);
|
|
|
|
|
|
2023-10-31 19:28:40 +01:00
|
|
|
if (pipe->data.size() == size) {
|
2023-12-31 12:30:49 +01:00
|
|
|
pipe->data.clear();
|
2023-10-31 19:28:40 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::memmove(pipe->data.data(), pipe->data.data() + size,
|
|
|
|
|
pipe->data.size() - size);
|
|
|
|
|
pipe->data.resize(pipe->data.size() - size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-11-13 21:02:23 +01:00
|
|
|
|
|
|
|
|
file->event.emit(orbis::kEvFiltWrite);
|
2023-10-31 19:28:40 +01:00
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static orbis::ErrorCode pipe_write(orbis::File *file, orbis::Uio *uio,
|
|
|
|
|
orbis::Thread *thread) {
|
2024-01-04 01:53:58 +01:00
|
|
|
auto pipe = static_cast<orbis::Pipe *>(file)->other;
|
2023-12-31 12:30:49 +01:00
|
|
|
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file);
|
2023-10-31 19:28:40 +01:00
|
|
|
|
2023-12-31 12:30:49 +01:00
|
|
|
std::size_t cnt = 0;
|
2023-10-31 19:28:40 +01:00
|
|
|
for (auto vec : std::span(uio->iov, uio->iovcnt)) {
|
|
|
|
|
auto offset = pipe->data.size();
|
|
|
|
|
pipe->data.resize(offset + vec.len);
|
2023-12-31 12:30:49 +01:00
|
|
|
ORBIS_RET_ON_ERROR(orbis::ureadRaw(pipe->data.data(), vec.base, vec.len));
|
|
|
|
|
cnt += vec.len;
|
2023-10-31 19:28:40 +01:00
|
|
|
}
|
2023-11-13 21:02:23 +01:00
|
|
|
|
|
|
|
|
file->event.emit(orbis::kEvFiltRead);
|
|
|
|
|
pipe->cv.notify_one(file->mtx);
|
2023-12-31 12:30:49 +01:00
|
|
|
uio->resid -= cnt;
|
|
|
|
|
uio->offset += cnt;
|
|
|
|
|
|
|
|
|
|
ORBIS_LOG_ERROR(__FUNCTION__, thread->name, thread->tid, file, uio->resid, uio->offset, file->nextOff, cnt);
|
|
|
|
|
thread->where();
|
|
|
|
|
return{};
|
2023-10-31 19:28:40 +01:00
|
|
|
}
|
|
|
|
|
|
2023-12-31 12:30:49 +01:00
|
|
|
static orbis::FileOps pipe_ops = {
|
|
|
|
|
.read = pipe_read,
|
|
|
|
|
.write = pipe_write,
|
|
|
|
|
};
|
2023-10-31 19:28:40 +01:00
|
|
|
|
2024-01-04 01:53:58 +01:00
|
|
|
std::pair<orbis::Ref<orbis::Pipe>, orbis::Ref<orbis::Pipe>> orbis::createPipe() {
|
|
|
|
|
auto a = knew<Pipe>();
|
|
|
|
|
auto b = knew<Pipe>();
|
|
|
|
|
a->ops = &pipe_ops;
|
|
|
|
|
b->ops = &pipe_ops;
|
|
|
|
|
a->other = b;
|
|
|
|
|
b->other = a;
|
|
|
|
|
return {a, b};
|
2023-10-31 19:28:40 +01:00
|
|
|
}
|