mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-09-01 22:59:37 +00:00
Properly catch exceptions in C API
This commit is contained in:
@ -60,6 +60,10 @@ typedef enum { // Don't change, it must match plog severity
|
||||
RTC_LOG_VERBOSE = 6
|
||||
} rtcLogLevel;
|
||||
|
||||
const int RTC_ERR_SUCCESS = 0;
|
||||
const int RTC_ERR_INVALID = -1; // invalid argument
|
||||
const int RTC_ERR_FAILURE = -2; // runtime error
|
||||
|
||||
typedef struct {
|
||||
const char **iceServers;
|
||||
int iceServersCount;
|
||||
@ -129,7 +133,8 @@ int rtcGetAvailableAmount(int id); // total size available to receive
|
||||
int rtcSetAvailableCallback(int id, availableCallbackFunc cb);
|
||||
int rtcReceiveMessage(int id, char *buffer, int *size);
|
||||
|
||||
// Cleanup
|
||||
// Optional preload and cleanup
|
||||
void rtcPreload();
|
||||
void rtcCleanup();
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -235,7 +235,7 @@ namespace {
|
||||
template <class F, class... Args>
|
||||
std::future<std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>> thread_call(F &&f,
|
||||
Args &&... args) {
|
||||
using R = std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>;
|
||||
using R = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>;
|
||||
std::packaged_task<R()> task(std::bind(f, std::forward<Args>(args)...));
|
||||
std::future<R> future = task.get_future();
|
||||
std::thread t(std::move(task));
|
||||
|
@ -42,6 +42,9 @@ PeerConnection::PeerConnection(const Configuration &config)
|
||||
: mConfig(config), mCertificate(make_certificate()), mState(State::New),
|
||||
mGatheringState(GatheringState::New) {
|
||||
PLOG_VERBOSE << "Creating PeerConnection";
|
||||
|
||||
if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd)
|
||||
throw std::invalid_argument("Invalid port range");
|
||||
}
|
||||
|
||||
PeerConnection::~PeerConnection() {
|
||||
|
264
src/rtc.cpp
264
src/rtc.cpp
@ -29,6 +29,7 @@
|
||||
|
||||
#include <exception>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
@ -36,14 +37,6 @@ using namespace rtc;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
#define CATCH(statement) \
|
||||
try { \
|
||||
statement; \
|
||||
} catch (const std::exception &e) { \
|
||||
PLOG_ERROR << e.what(); \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
std::unordered_map<int, shared_ptr<PeerConnection>> peerConnectionMap;
|
||||
@ -71,14 +64,18 @@ void setUserPointer(int i, void *ptr) {
|
||||
|
||||
shared_ptr<PeerConnection> getPeerConnection(int id) {
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = peerConnectionMap.find(id);
|
||||
return it != peerConnectionMap.end() ? it->second : nullptr;
|
||||
if (auto it = peerConnectionMap.find(id); it != peerConnectionMap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw std::invalid_argument("PeerConnection ID does not exist");
|
||||
}
|
||||
|
||||
shared_ptr<DataChannel> getDataChannel(int id) {
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = dataChannelMap.find(id);
|
||||
return it != dataChannelMap.end() ? it->second : nullptr;
|
||||
if (auto it = dataChannelMap.find(id); it != dataChannelMap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw std::invalid_argument("DataChannel ID does not exist");
|
||||
}
|
||||
|
||||
int emplacePeerConnection(shared_ptr<PeerConnection> ptr) {
|
||||
@ -95,27 +92,27 @@ int emplaceDataChannel(shared_ptr<DataChannel> ptr) {
|
||||
return dc;
|
||||
}
|
||||
|
||||
bool erasePeerConnection(int pc) {
|
||||
void erasePeerConnection(int pc) {
|
||||
std::lock_guard lock(mutex);
|
||||
if (peerConnectionMap.erase(pc) == 0)
|
||||
return false;
|
||||
throw std::invalid_argument("PeerConnection ID does not exist");
|
||||
userPointerMap.erase(pc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool eraseDataChannel(int dc) {
|
||||
void eraseDataChannel(int dc) {
|
||||
std::lock_guard lock(mutex);
|
||||
if (dataChannelMap.erase(dc) == 0)
|
||||
return false;
|
||||
throw std::invalid_argument("DataChannel ID does not exist");
|
||||
userPointerMap.erase(dc);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
shared_ptr<WebSocket> getWebSocket(int id) {
|
||||
std::lock_guard lock(mutex);
|
||||
auto it = webSocketMap.find(id);
|
||||
return it != webSocketMap.end() ? it->second : nullptr;
|
||||
if (auto it = webSocketMap.find(id); it != webSocketMap.end())
|
||||
return it->second;
|
||||
else
|
||||
throw std::invalid_argument("WebSocket ID does not exist");
|
||||
}
|
||||
|
||||
int emplaceWebSocket(shared_ptr<WebSocket> ptr) {
|
||||
@ -125,12 +122,11 @@ int emplaceWebSocket(shared_ptr<WebSocket> ptr) {
|
||||
return ws;
|
||||
}
|
||||
|
||||
bool eraseWebSocket(int ws) {
|
||||
void eraseWebSocket(int ws) {
|
||||
std::lock_guard lock(mutex);
|
||||
if (webSocketMap.erase(ws) == 0)
|
||||
return false;
|
||||
throw std::invalid_argument("WebSocket ID does not exist");
|
||||
userPointerMap.erase(ws);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -142,9 +138,28 @@ shared_ptr<Channel> getChannel(int id) {
|
||||
if (auto it = webSocketMap.find(id); it != webSocketMap.end())
|
||||
return it->second;
|
||||
#endif
|
||||
return nullptr;
|
||||
throw std::invalid_argument("DataChannel or WebSocket ID does not exist");
|
||||
}
|
||||
|
||||
template <typename F> int wrap(F func) {
|
||||
try {
|
||||
return func();
|
||||
|
||||
} catch (const std::invalid_argument &e) {
|
||||
PLOG_ERROR << e.what();
|
||||
return RTC_ERR_INVALID;
|
||||
} catch (const std::exception &e) {
|
||||
PLOG_ERROR << e.what();
|
||||
return RTC_ERR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#define WRAP(statement) \
|
||||
wrap([&]() { \
|
||||
statement; \
|
||||
return RTC_ERR_SUCCESS; \
|
||||
})
|
||||
|
||||
} // namespace
|
||||
|
||||
void rtcInitLogger(rtcLogLevel level) { InitLogger(static_cast<LogLevel>(level)); }
|
||||
@ -152,6 +167,7 @@ void rtcInitLogger(rtcLogLevel level) { InitLogger(static_cast<LogLevel>(level))
|
||||
void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); }
|
||||
|
||||
int rtcCreatePeerConnection(const rtcConfiguration *config) {
|
||||
return WRAP({
|
||||
Configuration c;
|
||||
for (int i = 0; i < config->iceServersCount; ++i)
|
||||
c.iceServers.emplace_back(string(config->iceServers[i]));
|
||||
@ -162,13 +178,12 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
|
||||
}
|
||||
|
||||
return emplacePeerConnection(std::make_shared<PeerConnection>(c));
|
||||
});
|
||||
}
|
||||
|
||||
int rtcDeletePeerConnection(int pc) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
peerConnection->onDataChannel(nullptr);
|
||||
peerConnection->onLocalDescription(nullptr);
|
||||
peerConnection->onLocalCandidate(nullptr);
|
||||
@ -176,25 +191,21 @@ int rtcDeletePeerConnection(int pc) {
|
||||
peerConnection->onGatheringStateChange(nullptr);
|
||||
|
||||
erasePeerConnection(pc);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcCreateDataChannel(int pc, const char *label) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
int dc = emplaceDataChannel(peerConnection->createDataChannel(string(label)));
|
||||
void *ptr = getUserPointer(pc);
|
||||
rtcSetUserPointer(dc, ptr);
|
||||
rtcSetUserPointer(dc, getUserPointer(pc));
|
||||
return dc;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcDeleteDataChannel(int dc) {
|
||||
return WRAP({
|
||||
auto dataChannel = getDataChannel(dc);
|
||||
if (!dataChannel)
|
||||
return -1;
|
||||
|
||||
dataChannel->onOpen(nullptr);
|
||||
dataChannel->onClosed(nullptr);
|
||||
dataChannel->onError(nullptr);
|
||||
@ -203,21 +214,21 @@ int rtcDeleteDataChannel(int dc) {
|
||||
dataChannel->onAvailable(nullptr);
|
||||
|
||||
eraseDataChannel(dc);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
#if RTC_ENABLE_WEBSOCKET
|
||||
int rtcCreateWebSocket(const char *url) {
|
||||
return WRAP({
|
||||
auto ws = std::make_shared<WebSocket>();
|
||||
ws->open(url);
|
||||
return emplaceWebSocket(ws);
|
||||
});
|
||||
}
|
||||
|
||||
int rtcDeleteWebsocket(int ws) {
|
||||
return WRAP({
|
||||
auto webSocket = getWebSocket(ws);
|
||||
if (!webSocket)
|
||||
return -1;
|
||||
|
||||
webSocket->onOpen(nullptr);
|
||||
webSocket->onClosed(nullptr);
|
||||
webSocket->onError(nullptr);
|
||||
@ -226,16 +237,13 @@ int rtcDeleteWebsocket(int ws) {
|
||||
webSocket->onAvailable(nullptr);
|
||||
|
||||
eraseWebSocket(ws);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
peerConnection->onDataChannel([pc, cb](std::shared_ptr<DataChannel> dataChannel) {
|
||||
int dc = emplaceDataChannel(dataChannel);
|
||||
@ -245,87 +253,85 @@ int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) {
|
||||
});
|
||||
else
|
||||
peerConnection->onDataChannel(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
peerConnection->onLocalDescription([pc, cb](const Description &desc) {
|
||||
cb(string(desc).c_str(), desc.typeString().c_str(), getUserPointer(pc));
|
||||
});
|
||||
else
|
||||
peerConnection->onLocalDescription(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
peerConnection->onLocalCandidate([pc, cb](const Candidate &cand) {
|
||||
cb(cand.candidate().c_str(), cand.mid().c_str(), getUserPointer(pc));
|
||||
});
|
||||
else
|
||||
peerConnection->onLocalCandidate(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
peerConnection->onStateChange([pc, cb](PeerConnection::State state) {
|
||||
cb(static_cast<rtcState>(state), getUserPointer(pc));
|
||||
});
|
||||
else
|
||||
peerConnection->onStateChange(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetGatheringStateChangeCallback(int pc, gatheringStateCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
peerConnection->onGatheringStateChange([pc, cb](PeerConnection::GatheringState state) {
|
||||
cb(static_cast<rtcGatheringState>(state), getUserPointer(pc));
|
||||
});
|
||||
else
|
||||
peerConnection->onGatheringStateChange(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetRemoteDescription(int pc, const char *sdp, const char *type) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
CATCH(peerConnection->setRemoteDescription({string(sdp), type ? string(type) : ""}));
|
||||
return 0;
|
||||
if (!sdp)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
peerConnection->setRemoteDescription({string(sdp), type ? string(type) : ""});
|
||||
});
|
||||
}
|
||||
|
||||
int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
CATCH(peerConnection->addRemoteCandidate({string(cand), mid ? string(mid) : ""}))
|
||||
return 0;
|
||||
if (!cand)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
peerConnection->addRemoteCandidate({string(cand), mid ? string(mid) : ""});
|
||||
});
|
||||
}
|
||||
|
||||
int rtcGetLocalAddress(int pc, char *buffer, int size) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (!buffer)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
if (auto addr = peerConnection->localAddress()) {
|
||||
size = std::min(size_t(size - 1), addr->size());
|
||||
@ -333,13 +339,15 @@ int rtcGetLocalAddress(int pc, char *buffer, int size) {
|
||||
buffer[size] = '\0';
|
||||
return size + 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcGetRemoteAddress(int pc, char *buffer, int size) {
|
||||
return WRAP({
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
if (!peerConnection)
|
||||
return -1;
|
||||
|
||||
if (!buffer)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
if (auto addr = peerConnection->remoteAddress()) {
|
||||
size = std::min(size_t(size - 1), addr->size());
|
||||
@ -347,65 +355,62 @@ int rtcGetRemoteAddress(int pc, char *buffer, int size) {
|
||||
buffer[size] = '\0';
|
||||
return size + 1;
|
||||
}
|
||||
return -1;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcGetDataChannelLabel(int dc, char *buffer, int size) {
|
||||
return WRAP({
|
||||
auto dataChannel = getDataChannel(dc);
|
||||
if (!dataChannel)
|
||||
return -1;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
if (!buffer)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
if (size >= 0) {
|
||||
string label = dataChannel->label();
|
||||
size = std::min(size_t(size - 1), label.size());
|
||||
std::copy(label.data(), label.data() + size, buffer);
|
||||
buffer[size] = '\0';
|
||||
return size + 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetOpenCallback(int id, openCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onOpen([id, cb]() { cb(getUserPointer(id)); });
|
||||
else
|
||||
channel->onOpen(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetClosedCallback(int id, closedCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onClosed([id, cb]() { cb(getUserPointer(id)); });
|
||||
else
|
||||
channel->onClosed(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetErrorCallback(int id, errorCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onError([id, cb](const string &error) { cb(error.c_str(), getUserPointer(id)); });
|
||||
channel->onError(
|
||||
[id, cb](const string &error) { cb(error.c_str(), getUserPointer(id)); });
|
||||
else
|
||||
channel->onError(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetMessageCallback(int id, messageCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onMessage(
|
||||
[id, cb](const binary &b) {
|
||||
@ -414,96 +419,82 @@ int rtcSetMessageCallback(int id, messageCallbackFunc cb) {
|
||||
[id, cb](const string &s) { cb(s.c_str(), -1, getUserPointer(id)); });
|
||||
else
|
||||
channel->onMessage(nullptr);
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSendMessage(int id, const char *data, int size) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (!data)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
if (size >= 0) {
|
||||
auto b = reinterpret_cast<const byte *>(data);
|
||||
CATCH(channel->send(binary(b, b + size)));
|
||||
channel->send(binary(b, b + size));
|
||||
return size;
|
||||
} else {
|
||||
string str(data);
|
||||
int len = str.size();
|
||||
CATCH(channel->send(std::move(str)));
|
||||
channel->send(std::move(str));
|
||||
return len;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
int rtcGetBufferedAmount(int id) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
CATCH(return int(channel->bufferedAmount()));
|
||||
return int(channel->bufferedAmount());
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetBufferedAmountLowThreshold(int id, int amount) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
CATCH(channel->setBufferedAmountLowThreshold(size_t(amount)));
|
||||
return 0;
|
||||
channel->setBufferedAmountLowThreshold(size_t(amount));
|
||||
});
|
||||
}
|
||||
|
||||
int rtcSetBufferedAmountLowCallback(int id, bufferedAmountLowCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onBufferedAmountLow([id, cb]() { cb(getUserPointer(id)); });
|
||||
else
|
||||
channel->onBufferedAmountLow(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcGetAvailableAmount(int id) {
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
CATCH(return int(channel->availableAmount()));
|
||||
return WRAP({ return int(getChannel(id)->availableAmount()); });
|
||||
}
|
||||
|
||||
int rtcSetAvailableCallback(int id, availableCallbackFunc cb) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (cb)
|
||||
channel->onOpen([id, cb]() { cb(getUserPointer(id)); });
|
||||
else
|
||||
channel->onOpen(nullptr);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
int rtcReceiveMessage(int id, char *buffer, int *size) {
|
||||
return WRAP({
|
||||
auto channel = getChannel(id);
|
||||
if (!channel)
|
||||
return -1;
|
||||
|
||||
if (!size)
|
||||
return -1;
|
||||
|
||||
CATCH({
|
||||
auto message = channel->receive();
|
||||
if (!message)
|
||||
return 0;
|
||||
if (!buffer || !size)
|
||||
throw std::invalid_argument("Unexpected null pointer");
|
||||
|
||||
if (auto message = channel->receive())
|
||||
return std::visit( //
|
||||
overloaded{ //
|
||||
[&](const binary &b) {
|
||||
*size = std::min(*size, int(b.size()));
|
||||
auto data = reinterpret_cast<const char *>(b.data());
|
||||
std::copy(data, data + *size, buffer);
|
||||
return *size;
|
||||
return 1;
|
||||
},
|
||||
[&](const string &s) {
|
||||
int len = std::min(*size - 1, int(s.size()));
|
||||
@ -512,10 +503,13 @@ int rtcReceiveMessage(int id, char *buffer, int *size) {
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
*size = -(len + 1);
|
||||
return len + 1;
|
||||
return 1;
|
||||
}},
|
||||
*message);
|
||||
else
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
void rtcPreload() { rtc::Preload(); }
|
||||
void rtcCleanup() { rtc::Cleanup(); }
|
||||
|
@ -35,7 +35,8 @@ using chrono::steady_clock;
|
||||
template <class T> weak_ptr<T> make_weak_ptr(shared_ptr<T> ptr) { return ptr; }
|
||||
|
||||
size_t benchmark(milliseconds duration) {
|
||||
InitLogger(LogLevel::Warning);
|
||||
rtc::InitLogger(LogLevel::Warning);
|
||||
rtc::Preload();
|
||||
|
||||
Configuration config1;
|
||||
// config1.iceServers.emplace_back("stun:stun.l.google.com:19302");
|
||||
@ -177,19 +178,17 @@ size_t benchmark(milliseconds duration) {
|
||||
pc2->close();
|
||||
this_thread::sleep_for(1s);
|
||||
|
||||
rtc::Cleanup();
|
||||
return goodput;
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK_MAIN
|
||||
int main(int argc, char **argv) {
|
||||
try {
|
||||
rtc::Preload();
|
||||
|
||||
size_t goodput = benchmark(30s);
|
||||
if (goodput == 0)
|
||||
throw runtime_error("No data received");
|
||||
|
||||
rtc::Cleanup();
|
||||
return 0;
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
|
Reference in New Issue
Block a user