Skip to content

Instantly share code, notes, and snippets.

@domob1812
Last active August 15, 2019 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domob1812/96c3371cb5ce8618d179345541bf065f to your computer and use it in GitHub Desktop.
Save domob1812/96c3371cb5ce8618d179345541bf065f to your computer and use it in GitHub Desktop.
libjson-rpc-cpp threading deadlock
#!/bin/sh -e
jsonrpcstub test.json --cpp-client=TestRpcClient --cpp-client-file=client.h
jsonrpcstub test.json --cpp-server=TestServerStub --cpp-server-file=serverstub.h
PKGS="libjsonrpccpp-client libjsonrpccpp-server libglog"
CFLAGS="`pkg-config --cflags ${PKGS}` -std=c++14 -Wall -Wextra -Werror"
LIBS="-L/usr/local/lib `pkg-config --libs ${PKGS}` -lpthread"
g++ -g -O0 -o client client.cpp ${CFLAGS} ${LIBS}
g++ -g -O0 -o server server.cpp ${CFLAGS} ${LIBS}
#include "client.h"
#include <jsonrpccpp/client/connectors/httpclient.h>
#include <glog/logging.h>
#include <chrono>
#include <cstdlib>
#include <thread>
namespace
{
void
CallWait (const std::string& rpcUrl)
{
jsonrpc::HttpClient httpClient(rpcUrl);
httpClient.SetTimeout (60000);
TestRpcClient rpc(httpClient);
rpc.wait ();
}
} // anonymous namespace
int
main ()
{
const std::string rpcUrl = "http://localhost:9999";
std::thread call1([&] ()
{
LOG (INFO) << "Call 1";
CallWait (rpcUrl);
});
std::thread call2([&] ()
{
LOG (INFO) << "Call 2";
CallWait (rpcUrl);
});
jsonrpc::HttpClient httpClient(rpcUrl);
TestRpcClient rpc(httpClient);
while (rpc.count () < 2)
std::this_thread::sleep_for (std::chrono::milliseconds (10));
rpc.release ();
call1.join ();
call2.join ();
return EXIT_SUCCESS;
}
#include "serverstub.h"
#include <jsonrpccpp/server/connectors/httpserver.h>
#include <glog/logging.h>
#include <atomic>
#include <chrono>
#include <cstdlib>
#include <thread>
namespace
{
class TestServer : public TestServerStub
{
private:
std::atomic<bool> done;
std::atomic<unsigned> cnt;
public:
explicit TestServer (jsonrpc::AbstractServerConnector& conn)
: TestServerStub(conn)
{
done = false;
cnt = 0;
StartListening ();
}
~TestServer ()
{
StopListening ();
}
void
wait () override
{
++cnt;
LOG (INFO) << "Wait called, count " << cnt;
while (!done)
std::this_thread::sleep_for (std::chrono::milliseconds (10));
}
int
count () override
{
return cnt;
}
void
release () override
{
LOG (INFO) << "Releasing waits...";
done = true;
}
bool
isDone () const
{
return done;
}
};
} // anonymous namespace
int
main ()
{
jsonrpc::HttpServer httpServer(9999);
TestServer srv(httpServer);
while (!srv.isDone ())
std::this_thread::sleep_for (std::chrono::milliseconds (10));
return EXIT_SUCCESS;
}
[
{
"name": "wait",
"params": {}
},
{
"name": "count",
"params": {},
"returns": 0
},
{
"name": "release",
"params": {}
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment