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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
//
// Created by Gyuhwan Park on 2022/05/06.
//
#ifndef ULALACA_PROJECTIONTHREAD_HPP
#define ULALACA_PROJECTIONTHREAD_HPP
#include <memory>
#include <thread>
#include <queue>
#include <future>
#include "UnixSocket.hpp"
#include "UlalacaMessages.hpp"
#include "ulalaca.hpp"
using MallocFreeDeleter = std::function<void(void *)>;
class ProjectionThread {
public:
explicit ProjectionThread(
XrdpUlalaca &xrdpUlalaca,
UnixSocket &socket
);
void start();
void stop();
void handleEvent(XrdpEvent &event);
private:
void mainLoop();
void ioLoop();
std::unique_ptr<projector::MessageHeader, MallocFreeDeleter> nextHeader();
template<typename T>
std::unique_ptr<T, MallocFreeDeleter> read(size_t size) {
assert(size != 0);
auto promise = std::promise<std::unique_ptr<uint8_t>>();
{
std::scoped_lock<std::mutex> scopedReadTasksLock(_readTasksLock);
_readTasks.emplace(size, promise);
}
auto pointer = promise.get_future().get();
return std::move(std::unique_ptr<T, MallocFreeDeleter>(
reinterpret_cast<T *>(pointer.release()),
free
));
}
void write(const void *pointer, size_t size);
template <typename T>
void writeMessage(projector::MessageType messageType, T message) {
auto header = projector::MessageHeader {
(uint16_t) messageType,
0, 0,
0,
sizeof(T)
};
write(&header, sizeof(header));
write(&message, sizeof(T));
}
XrdpUlalaca &_xrdpUlalaca;
UnixSocket &_socket;
bool _isTerminated;
std::thread _projectorThread;
std::thread _ioThread;
std::mutex _writeTasksLock;
std::mutex _readTasksLock;
std::queue<std::pair<size_t, std::unique_ptr<uint8_t, MallocFreeDeleter>>> _writeTasks;
std::queue<std::pair<size_t, std::promise<std::unique_ptr<uint8_t>> &>> _readTasks;
};
#endif //ULALACA_PROJECTIONTHREAD_HPP
|