|
|
|
@ -21,6 +21,8 @@
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
constexpr int64_t const timeout_secs = 10;
|
|
|
|
|
|
|
|
|
|
struct user_data
|
|
|
|
|
{
|
|
|
|
|
struct lws * connection = nullptr;
|
|
|
|
@ -32,44 +34,12 @@ struct user_data
|
|
|
|
|
std::unordered_map<uint32_t, std::promise<webfuse::messagereader>> pending_responses;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
|
void do_receive(void * in, int len, lws* wsi, user_data * data)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
|
|
|
|
|
void *user, void *in, size_t len)
|
|
|
|
|
{
|
|
|
|
|
auto const * protocol = lws_get_protocol(wsi);
|
|
|
|
|
if (nullptr == protocol) { return 0; }
|
|
|
|
|
if (&ws_server_callback != protocol->callback) { return 0; }
|
|
|
|
|
|
|
|
|
|
auto * data = reinterpret_cast<user_data *>(protocol->user);
|
|
|
|
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
switch(reason)
|
|
|
|
|
{
|
|
|
|
|
case LWS_CALLBACK_ESTABLISHED:
|
|
|
|
|
if (nullptr == data->connection)
|
|
|
|
|
{
|
|
|
|
|
data->connection = wsi;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LWS_CALLBACK_CLOSED:
|
|
|
|
|
if (wsi == data->connection)
|
|
|
|
|
{
|
|
|
|
|
data->connection = nullptr;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LWS_CALLBACK_RECEIVE:
|
|
|
|
|
{
|
|
|
|
|
auto * fragment = reinterpret_cast<char*>(in);
|
|
|
|
|
data->current_message.append(fragment, len);
|
|
|
|
|
if (lws_is_final_fragment(wsi))
|
|
|
|
|
if (0 != lws_is_final_fragment(wsi))
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
@ -77,7 +47,7 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
|
|
|
|
|
uint32_t id = reader.read_u32();
|
|
|
|
|
uint8_t message_type = reader.read_u8();
|
|
|
|
|
|
|
|
|
|
std::lock_guard lock(data->mut);
|
|
|
|
|
std::lock_guard<std::mutex> lock(data->mut);
|
|
|
|
|
auto it = data->pending_responses.find(id);
|
|
|
|
|
if (it != data->pending_responses.end())
|
|
|
|
|
{
|
|
|
|
@ -99,11 +69,46 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
|
|
|
|
|
// ToDo: log invalid message
|
|
|
|
|
std::cout << "warning: invalid message" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
|
|
|
|
|
void *user, void *in, size_t len)
|
|
|
|
|
{
|
|
|
|
|
auto const * protocol = lws_get_protocol(wsi);
|
|
|
|
|
if (nullptr == protocol) { return 0; }
|
|
|
|
|
if (&ws_server_callback != protocol->callback) { return 0; }
|
|
|
|
|
|
|
|
|
|
auto * data = reinterpret_cast<user_data *>(protocol->user);
|
|
|
|
|
|
|
|
|
|
int result = 0;
|
|
|
|
|
switch(reason)
|
|
|
|
|
{
|
|
|
|
|
case LWS_CALLBACK_ESTABLISHED:
|
|
|
|
|
if (nullptr == data->connection)
|
|
|
|
|
{
|
|
|
|
|
data->connection = wsi;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LWS_CALLBACK_CLOSED:
|
|
|
|
|
if (wsi == data->connection)
|
|
|
|
|
{
|
|
|
|
|
data->connection = nullptr;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LWS_CALLBACK_RECEIVE:
|
|
|
|
|
do_receive(in, len, wsi, data);
|
|
|
|
|
break;
|
|
|
|
|
case LWS_CALLBACK_SERVER_WRITEABLE:
|
|
|
|
|
{
|
|
|
|
|
webfuse::messagewriter writer(webfuse::request_type::unknown);
|
|
|
|
@ -111,7 +116,7 @@ static int ws_server_callback(struct lws *wsi, enum lws_callback_reasons reason,
|
|
|
|
|
bool has_more = false;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock(data->mut);
|
|
|
|
|
std::lock_guard<std::mutex> lock(data->mut);
|
|
|
|
|
has_msg = !(data->requests.empty());
|
|
|
|
|
if (has_msg)
|
|
|
|
|
{
|
|
|
|
@ -181,7 +186,7 @@ public:
|
|
|
|
|
while (!shutdown_requested)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard lock(data.mut);
|
|
|
|
|
std::lock_guard<std::mutex> lock(data.mut);
|
|
|
|
|
if (!data.requests.empty())
|
|
|
|
|
{
|
|
|
|
|
if (nullptr != data.connection)
|
|
|
|
@ -264,7 +269,7 @@ messagereader ws_server::perform(messagewriter writer)
|
|
|
|
|
std::promise<messagereader> p;
|
|
|
|
|
f = p.get_future();
|
|
|
|
|
|
|
|
|
|
std::lock_guard lock(d->data.mut);
|
|
|
|
|
std::lock_guard<std::mutex> lock(d->data.mut);
|
|
|
|
|
uint32_t id = d->next_id();
|
|
|
|
|
writer.set_id(id);
|
|
|
|
|
d->data.requests.emplace(std::move(writer));
|
|
|
|
@ -272,7 +277,7 @@ messagereader ws_server::perform(messagewriter writer)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lws_cancel_service(d->context);
|
|
|
|
|
if(std::future_status::timeout == f.wait_for(std::chrono::seconds(10)))
|
|
|
|
|
if(std::future_status::timeout == f.wait_for(std::chrono::seconds(timeout_secs)))
|
|
|
|
|
{
|
|
|
|
|
throw std::runtime_error("timeout");
|
|
|
|
|
}
|
|
|
|
|