Skip to content

Commit 43ecb14

Browse files
committed
project: Integrate lib-datalane
This is a rather huge change that only affects how things are run internally. From the outside, everything should still run as it did before, while from the inside things now run drastically different. The new internals of lib-datalane are designed around the kernel API instead of being designed around the target use, which results in a much smoother experience, less lost data and higher control. Internally the new API allows us to remove the use of Signals, allowing us to instead properly wait using the Kernel itself. This results in quicker and much more stabler messages. We also now send the message size with the message itself, no longer rely on the message pipe type (everything is bytes) and largely have switched to callbacks instead of one huge loop. While things still execute on the same thread anyway, this results in cleaner overall code. ipc::server is now only using a single thread to keep track of connected and disconnected clients, which results in less overhead, but makes tracking new and old clients a little bit more difficult to do. This breaks: - Client Id (not implemented yet)
1 parent 95b37ce commit 43ecb14

9 files changed

+619
-493
lines changed

CMakeLists.txt

+1-17
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@ SET(lib-streamlabs-ipc_SOURCES
5555
"${PROJECT_SOURCE_DIR}/include/ipc-server-instance.hpp"
5656
"${PROJECT_SOURCE_DIR}/source/ipc-value.cpp"
5757
"${PROJECT_SOURCE_DIR}/include/ipc-value.hpp"
58-
"${PROJECT_SOURCE_DIR}/include/os-error.hpp"
59-
"${PROJECT_SOURCE_DIR}/source/os-namedsocket.cpp"
60-
"${PROJECT_SOURCE_DIR}/include/os-namedsocket.hpp"
61-
"${PROJECT_SOURCE_DIR}/source/os-signal.cpp"
62-
"${PROJECT_SOURCE_DIR}/include/os-signal.hpp"
63-
"${PROJECT_SOURCE_DIR}/source/os-signal-win.cpp"
64-
"${PROJECT_SOURCE_DIR}/include/os-signal-win.hpp"
6558
"${PROJECT_SOURCE_DIR}/include/util.h"
6659
)
6760
SET(Protobuf_IMPORT_DIRS
@@ -95,34 +88,27 @@ IF(WIN32)
9588
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
9689

9790
LIST(APPEND lib-streamlabs-ipc_SOURCES
98-
"${PROJECT_SOURCE_DIR}/include/os-namedsocket-win.hpp"
99-
"${PROJECT_SOURCE_DIR}/source/os-namedsocket-win.cpp"
10091
)
10192
LIST(APPEND lib-streamlabs-ipc_DEPS
102-
advapi32
103-
ole32
10493
)
10594
ELSEIF(APPLE)
10695
# MacOSX
10796

10897
LIST(APPEND lib-streamlabs-ipc_SOURCES
109-
"${PROJECT_SOURCE_DIR}/source/os-namedsocket-mac.cpp"
11098
)
11199
LIST(APPEND lib-streamlabs-ipc_DEPS
112100
)
113101
ELSEIF("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
114102
# Linux
115103

116104
LIST(APPEND lib-streamlabs-ipc_SOURCES
117-
"${PROJECT_SOURCE_DIR}/source/os-namedsocket-linux.cpp"
118105
)
119106
LIST(APPEND lib-streamlabs-ipc_DEPS
120107
)
121108
ELSEIF("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
122109
# FreeBSD
123110

124111
LIST(APPEND lib-streamlabs-ipc_SOURCES
125-
"${PROJECT_SOURCE_DIR}/source/os-namedsocket-freebsd.cpp"
126112
)
127113
LIST(APPEND lib-streamlabs-ipc_DEPS
128114
)
@@ -139,6 +125,7 @@ INCLUDE_DIRECTORIES(
139125
${PROJECT_SOURCE_DIR}/source
140126
${PROJECT_SOURCE_DIR}/include
141127
${PROJECT_SOURCE_DIR}/third-party/boost/
128+
${PROJECT_SOURCE_DIR}/third-party/lib-datalane/
142129
${Protobuf_INCLUDE_DIRS}
143130
${PROJECT_BINARY_DIR}
144131
)
@@ -163,9 +150,6 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME}
163150
################################################################################
164151
IF(BUILD_TESTS)
165152
ADD_SUBDIRECTORY(tests/shared)
166-
ADD_SUBDIRECTORY(tests/os-namedsocket/raw-data)
167-
ADD_SUBDIRECTORY(tests/os-namedsocket/read-no-sleep)
168-
ADD_SUBDIRECTORY(tests/os-namedsocket/single-in-single-out)
169153
ADD_SUBDIRECTORY(tests/ipc/simple-multi-client)
170154
ADD_SUBDIRECTORY(tests/ipc/synchronous-call)
171155
ENDIF(BUILD_TESTS)

include/ipc-client.hpp

+19-15
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,37 @@
1717

1818
#pragma once
1919
#include "ipc.hpp"
20-
#include "os-namedsocket.hpp"
21-
#include "os-signal.hpp"
2220
#include <string>
2321
#include <vector>
2422
#include <map>
2523
#include <mutex>
2624
#include <queue>
2725
#include <thread>
2826
#include <vector>
27+
#include "source/os/windows/named-pipe.hpp"
2928

3029
namespace ipc {
3130
typedef void(*call_return_t)(const void* data, const std::vector<ipc::value>& rval);
3231

3332
class client {
33+
std::unique_ptr<os::windows::named_pipe> m_socket;
34+
std::shared_ptr<os::async_op> m_wop, m_rop;
35+
std::vector<char> m_wbuf, m_rbuf;
36+
37+
bool m_authenticated = false;
38+
std::mutex m_lock;
39+
std::map<int64_t, std::pair<call_return_t, void*>> m_cb;
40+
41+
// Threading
42+
struct {
43+
std::thread worker;
44+
bool stop = false;
45+
} m_watcher;
46+
47+
void worker();
48+
void read_callback_init(os::error ec, size_t size);
49+
void read_callback_msg(os::error ec, size_t size);
50+
3451
public:
3552
client(std::string socketPath);
3653
virtual ~client();
@@ -44,18 +61,5 @@ namespace ipc {
4461
// Temporary helper
4562
std::vector<ipc::value> call_synchronous_helper(std::string cname, std::string fname, std::vector<ipc::value> args,
4663
std::chrono::nanoseconds timeout = std::chrono::milliseconds(5000000000));
47-
48-
private:
49-
std::unique_ptr<os::named_socket> m_socket;
50-
bool m_authenticated = false;
51-
std::map<int64_t, std::pair<call_return_t, void*>> m_cb;
52-
53-
private: // Threading
54-
bool m_stopWorkers = false;
55-
std::thread m_worker;
56-
std::mutex m_lock;
57-
static void worker_thread(client* ptr);
58-
std::shared_ptr<os::signal> m_readSignal;
59-
std::shared_ptr<os::signal> m_writeSignal;
6064
};
6165
}

include/ipc-server-instance.hpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,13 @@
1717

1818
#pragma once
1919
#include "ipc-server.hpp"
20-
#include "os-namedsocket.hpp"
21-
#include "os-signal.hpp"
2220
#include <condition_variable>
2321
#include <memory>
2422
#include <mutex>
2523
#include <queue>
2624
#include <thread>
2725
#include <vector>
26+
#include "source/os/windows/named-pipe.hpp"
2827

2928
namespace ipc {
3029
class server;
@@ -34,7 +33,7 @@ namespace ipc {
3433

3534
public:
3635
server_instance();
37-
server_instance(server* owner, std::shared_ptr<os::named_socket_connection> conn);
36+
server_instance(server* owner, std::shared_ptr<os::windows::named_pipe> conn);
3837
~server_instance();
3938

4039
bool is_alive();
@@ -44,18 +43,19 @@ namespace ipc {
4443
std::thread m_worker;
4544

4645
void worker();
47-
static void worker_main(server_instance* ptr) {
48-
ptr->worker();
49-
};
46+
void read_callback_init(os::error ec, size_t size);
47+
void read_callback_msg(os::error ec, size_t size);
48+
void write_callback(os::error ec, size_t size);
5049

5150
protected:
52-
std::shared_ptr<os::named_socket_connection> m_socket;
51+
std::shared_ptr<os::windows::named_pipe> m_socket;
52+
std::shared_ptr<os::async_op> m_wop, m_rop;
53+
std::vector<char> m_wbuf, m_rbuf;
54+
std::queue<std::vector<char>> m_write_queue;
5355

5456
private:
5557
server* m_parent = nullptr;
56-
os::ClientId_t m_clientId;
58+
int64_t m_clientId;
5759
bool m_isAuthenticated = false;
58-
std::shared_ptr<os::signal> m_readSignal;
59-
std::shared_ptr<os::signal> m_writeSignal;
6060
};
6161
}

include/ipc-server.hpp

+36-27
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,52 @@
1919
#include "ipc.hpp"
2020
#include "ipc-class.hpp"
2121
#include "ipc-server-instance.hpp"
22-
#include "os-namedsocket.hpp"
2322
#include <list>
2423
#include <map>
2524
#include <mutex>
2625
#include <queue>
2726
#include <string>
2827
#include <thread>
28+
#include "source/os/windows/named-pipe.hpp"
2929

3030
namespace ipc {
3131
class server_instance;
3232

33-
typedef bool(*server_connect_handler_t)(void*, os::ClientId_t);
34-
typedef void(*server_disconnect_handler_t)(void*, os::ClientId_t);
35-
typedef void(*server_message_handler_t)(void*, os::ClientId_t, const std::vector<char>&);
33+
typedef bool(*server_connect_handler_t)(void*, int64_t);
34+
typedef void(*server_disconnect_handler_t)(void*, int64_t);
35+
typedef void(*server_message_handler_t)(void*, int64_t, const std::vector<char>&);
3636

3737
class server {
38-
friend class server_instance;
38+
bool m_isInitialized = false;
39+
40+
// Functions
41+
std::map<std::string, std::shared_ptr<ipc::collection>> m_classes;
42+
43+
// Socket
44+
size_t backlog = 4;
45+
std::mutex m_sockets_mtx;
46+
std::list<std::shared_ptr<os::windows::named_pipe>> m_sockets;
47+
std::string m_socketPath = "";
48+
49+
// Client management.
50+
std::mutex m_clients_mtx;
51+
std::map<std::shared_ptr<os::windows::named_pipe>, std::shared_ptr<server_instance>> m_clients;
52+
53+
// Event Handlers
54+
std::pair<server_connect_handler_t, void*> m_handlerConnect;
55+
std::pair<server_disconnect_handler_t, void*> m_handlerDisconnect;
56+
std::pair<server_message_handler_t, void*> m_handlerMessage;
57+
58+
// Worker
59+
struct {
60+
std::thread worker;
61+
bool stop = false;
62+
} m_watcher;
63+
64+
void watcher();
65+
66+
void spawn_client(std::shared_ptr<os::windows::named_pipe> socket);
67+
void kill_client(std::shared_ptr<os::windows::named_pipe> socket);
3968

4069
public:
4170
server();
@@ -55,29 +84,9 @@ namespace ipc {
5584
bool register_collection(std::shared_ptr<ipc::collection> cls);
5685

5786
protected: // Client -> Server
58-
bool client_call_function(os::ClientId_t cid, std::string cname, std::string fname,
87+
bool client_call_function(int64_t cid, std::string cname, std::string fname,
5988
std::vector<ipc::value>& args, std::vector<ipc::value>& rval, std::string& errormsg);
6089

61-
private: // Threading
62-
std::thread m_worker;
63-
bool m_stopWorker = false;
64-
65-
static void worker_main(server* ptr);
66-
void worker_local();
67-
68-
private:
69-
std::unique_ptr<os::named_socket> m_socket;
70-
bool m_isInitialized = false;
71-
std::string m_socketPath = "";
72-
73-
// Client management.
74-
std::mutex m_clientLock;
75-
std::map<os::ClientId_t, std::shared_ptr<server_instance>> m_clients;
76-
std::map<std::string, std::shared_ptr<ipc::collection>> m_classes;
77-
78-
// Event Handlers
79-
std::pair<server_connect_handler_t, void*> m_handlerConnect;
80-
std::pair<server_disconnect_handler_t, void*> m_handlerDisconnect;
81-
std::pair<server_message_handler_t, void*> m_handlerMessage;
90+
friend class server_instance;
8291
};
8392
}

include/ipc.hpp

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@
2121
#include <vector>
2222

2323
namespace ipc {
24+
typedef uint32_t ipc_size_t;
25+
26+
inline void make_sendable(std::vector<char>& out, std::vector<char> const& in) {
27+
out.resize(in.size() + sizeof(ipc_size_t));
28+
memcpy(out.data() + sizeof(ipc_size_t), in.data(), in.size());
29+
reinterpret_cast<ipc_size_t&>(out[0]) = ipc_size_t(in.size());
30+
}
31+
32+
inline ipc_size_t read_size(std::vector<char> const& in) {
33+
return reinterpret_cast<const ipc_size_t&>(in[0]);
34+
}
35+
2436
class base {
2537
public:
2638
static std::string make_unique_id(std::string name, std::vector<type> parameters);

proto/ipc.proto

+1-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ message Authenticate {
3333
}
3434

3535
message AuthenticateReply {
36-
string read_event = 1;
37-
string write_event = 2;
36+
string password = 1;
3837
}
3938

0 commit comments

Comments
 (0)