C++ Function Completing Before Other Function Finishes - c++

I am coding a C++ program to interact with the internet using the C++ REST SDK. I have a main function and a webCommunication function. The code is similar to below:
void webCommunication(data, url)
{
//Communicate with the internet using the http_client
//Print output
}
int main()
{
//Obtain information from user
webCommunication(ans1, ans2);
system("PAUSE");
}
However, it seems that the main function is progressing before the webCommunication function is finished. If I make webCommunication a function type of string and have
cout << webCommunication(ans1, ans2) << endl;
But that still pauses and then prints the data retrieved. Normally, this would be fine, expect I am referring to the returned answer later on in the code. If the webCommunication isn't completed, the application crashes. Is there some kind of wait_until function I can use?
UPDATE: I have tried using a mutex suggested with no success. I also tried starting the function as a thread and then using the .join() with still no success.

If you declare your webCommunications() function as a
pplx::task<void> webCommunications()
{
}
Then you can use ".wait()" when calling the function. It will then wait until the function executes to continue. Looks like this:
pplx::task<void> webCommunications()
{
}
int main()
{
webCommunications().wait();
//Do other stuff
}

I think you are missing a keyword in the descriptions. ASYNCHRONOUS. This is indicating that it returns before finishing. If you need it to be synchronous, you should put a semaphore acquire right after the call and put a release into the callback code.
https://msdn.microsoft.com/en-us/library/jj950081.aspx
Modified code snippet from link above( added lock to callback ) :
// Creates an HTTP request and prints the length of the response stream.
pplx::task<void> HTTPStreamingAsync()
{
http_client client(L"http://www.fourthcoffee.com");
// Make the request and asynchronously process the response.
return client.request(methods::GET).then([](http_response response)
{
// Print the status code.
std::wostringstream ss;
ss << L"Server returned returned status code " << response.status_code() << L'.' << std::endl;
std::wcout << ss.str();
// TODO: Perform actions here reading from the response stream.
auto bodyStream = response.body();
// In this example, we print the length of the response to the console.
ss.str(std::wstring());
ss << L"Content length is " << response.headers().content_length() << L" bytes." << std::endl;
std::wcout << ss.str();
// RELEASE lock/semaphore/etc here.
mutex.unlock()
});
/* Sample output:
Server returned returned status code 200.
Content length is 63803 bytes.
*/
}
Note : Acquire the mutex after the function call to start web processing. Add to the callback code to release the mutex. In this way the main thread locks until the function actually finishes and then continues to 'pause'.
int main()
{
HttpStreamingAsync();
// Acquire lock to wait for complete
mutex.lock();
system("PAUSE");
}

Related

App crashes when it takes too long to reply in a ZMQ REQ/REP pattern

I am writing a plugin that interfaces with a desktop application through a ZeroMQ REQ/REP request-reply communication archetype. I can currently receive a request, but the application seemingly crashes if a reply is not sent quick enough.
I receive the request on a spawned thread and put it in a queue. This queue is processed in another thread, in which the processing function is invoked by the application periodically.
The message is correctly being received and processed, but the response cannot be sent until the next iteration of the function, as I cannot get the data from the application until then.
When this function is conditioned to send the response on the next iteration, the application will crash. However, if I send fake data as the response soon after receiving the request, in the first iteration, the application will not crash.
Constructing the socket
zmq::socket_t socket(m_context, ZMQ_REP);
socket.bind("tcp://*:" + std::to_string(port));
Receiving the message in the spawned thread
void ZMQReceiverV2::receiveRequests() {
nInfo(*m_logger) << "Preparing to receive requests";
while (m_isReceiving) {
zmq::message_t zmq_msg;
bool ok = m_respSocket.recv(&zmq_msg, ZMQ_NOBLOCK);
if (ok) {
// msg_str will be a binary string
std::string msg_str;
msg_str.assign(static_cast<char *>(zmq_msg.data()), zmq_msg.size());
nInfo(*m_logger) << "Received the message: " << msg_str;
std::pair<std::string, std::string> pair("", msg_str);
// adding to message queue
m_mutex.lock();
m_messages.push(pair);
m_mutex.unlock();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
nInfo(*m_logger) << "Done receiving requests";
}
Processing function on seperate thread
void ZMQReceiverV2::exportFrameAvailable()
// checking messages
// if the queue is not empty
m_mutex.lock();
if (!m_messages.empty()) {
nInfo(*m_logger) << "Reading message in queue";
smart_target::SMARTTargetCreateRequest id_msg;
std::pair<std::string, std::string> pair = m_messages.front();
std::string topic = pair.first;
std::string msg_str = pair.second;
processMsg(msg_str);
// removing just read message
m_messages.pop();
//m_respSocket.send(zmq::message_t()); wont crash if I reply here in this invocation
}
m_mutex.unlock();
// sending back the ID that has just been made, for it to be mapped
if (timeToSendReply()) {
sendReply(); // will crash, if I wait for this to be exectued on next invocation
}
}
My research shows that there is no time limit for the response to be sent, so this, seeming to be, timing issue, is strange.
Is there something that I am missing that will let me send the response on the second iteration of the processing function?
Revision 1:
I have edited my code, so that the responding socket only ever exists on one thread. Since I need to get information from the processing function to send, I created another queue, which is checked in the revised the function running on its own thread.
void ZMQReceiverV2::receiveRequests() {
zmq::socket_t socket = setupBindSocket(ZMQ_REP, 5557, "responder");
nInfo(*m_logger) << "Preparing to receive requests";
while (m_isReceiving) {
zmq::message_t zmq_msg;
bool ok = socket.recv(&zmq_msg, ZMQ_NOBLOCK);
if (ok) {
// does not crash if I call send helper here
// msg_str will be a binary string
std::string msg_str;
msg_str.assign(static_cast<char *>(zmq_msg.data()), zmq_msg.size());
NLogger::nInfo(*m_logger) << "Received the message: " << msg_str;
std::pair<std::string, std::string> pair("", msg_str);
// adding to message queue
m_mutex.lock();
m_messages.push(pair);
m_mutex.unlock();
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
if (!sendQueue.empty()) {
sendEntityCreationMessage(socket, sendQueue.front());
sendQueue.pop();
}
}
nInfo(*m_logger) << "Done receiving requests";
socket.close();
}
The function sendEntityCreationMessage() is a helper function that ultimately calls socket.send().
void ZMQReceiverV2::sendEntityCreationMessage(zmq::socket_t &socket, NUniqueID id) {
socket.send(zmq::message_t());
}
This code seems to be following the thread safety guidelines for sockets. Any suggestions?
Q : "Is there something that I am missing"
Yes,the ZeroMQ evangelisation, called a Zen-of-Zero, since ever promotes never try to share a Socket-instance, never try to block and never expect the world to act as one wishes.
This said, avoid touching the same Socket-instance from any non-local thread, except the one that has instantiated and owns the socket.
Last, but not least, the REQ/REP-Scalable Formal Communication Pattern Archetype is prone to fall into a deadlock, as a mandatory two-step dance must be obeyed - where one must keep the alternating sequence of calling .send()-.recv()-.send()-.recv()-.send()-...-methods, otherwise the principally distributed-system tandem of Finite State Automata (FSA) will unsalvageably end up in a mutual self-deadlock state of the dFSA.
In case one is planning to professionally build on ZeroMQ, the best next step is to re-read the fabulous Pieter HINTJENS' book "Code Connected: Volume 1". A piece of a hard read, yet definitely worth one's time, sweat, tears & efforts put in.

why GRPC AsyncClient throws Segfault when waiting for the Next result in the completion queue

I am using version 1.23.1 of the GRPC library.
I have an asynchronous RPC c++ Client class, which initiates each RPC with the following method:
void Client::SendTaskAsync(const Task& task) {
unique_lock<mutex> lock(mtx_);
cout << "Sending task with id " << task.id() << endl;
ClientContext context;
Status status;
unique_ptr<ClientAsyncResponseReader<Result>> rpc(
stub_->PrepareAsyncSendTask(&context, task, &queue_));
rpc->StartCall();
// Allocating memory to store result from RPC
Result* result = &results_.emplace_back();
int* tag = new int(results_.size() - 1);
rpc->Finish(result, &status, static_cast<void*>(tag));
}
In the main thread I call SendTaskAsync five times in a loop.
The Client class has a background thread informing when each RPC has returned a Result:
while (true) {
void* tag;
bool ok = false;
{
unique_lock<mutex> lock(mtx_);
cout << "Waiting the for next result" << endl;
const time_point<system_clock> deadline =
system_clock::now() + milliseconds(1000);
// SEGFAULT HERE, WHY?
GPR_ASSERT(queue_.AsyncNext(&tag, &ok, deadline));
}
if (ok) {
int index = *static_cast<int*>(tag);
cout << "Got result with tag " << index << endl;
} else {
cout << "Sleeping" << endl;
sleep_for(milliseconds(1000));
}
}
If I start my client, the following log is observed:
BACKGROUND: Waiting for the next result
MAIN THREAD: Sending task with id 0
BACKGROUND: Sleeping
MAIN THREAD: Sending task with id 1
MAIN THREAD: Sending task with id 2
MAIN THREAD: Sending task with id 3
MAIN THREAD: Sending task with id 4
BACKGROUND: Waiting for the next result
BACKGROUND: Segmentation fault (core dumped)
What happens is that
Background thread checks if a queue_ contains a result, there is none yet, so it goes to sleep;
Main thread makes 5 RPC that at the end should populate the queue_ with results;
Background thread wakes up and checks if a queue_ contains a result, AND CRASHES.
Any ideas why?
The code in the question is written according to this tutorial, which sends only one request and waits for a reply in the same thread.
If you want to use multiple threads, follow the client example here.

gRPC: How can RPC handlers properly detect if `Server` has been `Shutdown()`

Current, I'm using a hackish way – a global variable – to make RPC handlers able to detect that the Server has been (about to be) called Shutdown().
bool g_ServerIsNotDead = true; // Hack!
Status StreamServiceImpl::GetCurrentTemperature(ServerContext *context_,
const UpdateInterval *request_,
ServerWriter<Temperature> *stream_)
{
auto currentTemp = 100.0f;
while(g_ServerIsNotDead) // Hack!!!
{
qDebug() << QThread::currentThreadId() << currentTemp << "farenheit.";
Temperature message;
message.set_temperature(currentTemp);
stream_->Write(message);
QThread::sleep(2);
currentTemp += 1.0f;
}
return Status::OK;
}
void insideSomeFunction() {
// Testing shutdown 5 seconds later
QTimer::singleShot(std::chrono::seconds(5), this, [=]() {
qDebug() << "Shuting down!";
g_ServerIsNotDead = false; // Hack!!
this->server->Shutdown(); // This method actually blocks until all RPC handlers have exited, believe it or not!
emit shutdown();
qDebug() << "All dead.";
});
}
Ref: https://github.com/C0D1UM/grpc-qt-example/blob/master/rpc_server/hellostream_server.cpp
It would be really nice if I could somehow check that Server has been Shutdown() from grpc::ServerContext, but I didn't see any relevant methods to achieve this.
Even better if someone could propose a way to take out the while loop completely (?). I'm using Qt so everything is event-driven.
So, I think it's worth making clear what Shutdown does. There's a detailed comment about this but basically, server Shutdown doesn't fail, cancel, or kill your existing in-progress calls (unless you use the deadline argument and the gRPC C++ async API).
Rather, it stops listening for new connections, stops accepting new calls, fails requested-but-not-yet-accepted calls. If you want to fail or terminate your calls at shutdown, you can do it at application-level code as you've done above.
I would just recommend that instead of using a global variable, you should use a member function of your StreamServiceImpl class so that you can support multiple services running in the same process if you choose.
We can use ServerContext::IsCancelled as a breaking/termination criteria in streaming APIs. I changed GetCurrentTemperature(...) as follows (just replaced g_ServerIsNotDead with !context_->IsCancelled()) and it worked:
Status StreamServiceImpl::GetCurrentTemperature(ServerContext *context_,
const UpdateInterval *request_,
ServerWriter<Temperature> *stream_) {
auto currentTemp = 100.0f;
while(!context_->IsCancelled) {
qDebug() << QThread::currentThreadId() << currentTemp << "farenheit.";
Temperature message;
message.set_temperature(currentTemp);
stream_->Write(message);
QThread::sleep(2);
currentTemp += 1.0f;
}
return Status::OK;
}

AMQP-CPP RabbitMQ async event based consumer not consuming anything

I'm using the AMQ-CPP library (https://github.com/CopernicaMarketingSoftware/AMQP-CPP) to connect to an existing queue I've created but I'm unable to read anything. I've tested that the queue works using another library (https://github.com/alanxz/SimpleAmqpClient, it works and I consume messages), but it uses a polling approach and I need an event based one.
My code looks like (based on the provided example):
int main()
{
auto *poll = EV_DEFAULT;
// handler for libev (so we don't have to implement AMQP::TcpHandler!)
AMQP::LibEvHandler handler(poll);
// make a connection
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"));
// we need a channel too
AMQP::TcpChannel channel(&connection);
// Define callbacks and start
auto messageCb = [&channel](
const AMQP::Message &message, uint64_t deliveryTag,
bool redelivered)
{
std::cout << "message received" << std::endl;
// acknowledge the message
channel.ack(deliveryTag);
processMessage(message.routingKey(), message.body());
};
// callback function that is called when the consume operation starts
auto startCb = [](const std::string &consumertag) {
std::cout << "consume operation started: " << consumertag << std::endl;
};
// callback function that is called when the consume operation failed
auto errorCb = [](const char *message) {
std::cout << "consume operation failed" << std::endl;
};
channel.consume("domoqueue")
.onReceived(messageCb)
.onSuccess(startCb)
.onError(errorCb);
// run the poll
ev_run(poll, 0);
// done
return 0;
}
I'm running the code in a Raspberry Pi having :
Linux raspberrypi 4.4.26-v7+ #915 SMP Thu Oct 20 17:08:44 BST 2016 armv7l GNU/Linux
What can be the problem? Probably I'm missing some configuration parameters for the queue... I've placed some debug traces and the channel creation does not take place. It blocks in the connection statement:
AMQP::TcpConnection connection(&handler, AMQP::Address("amqp://localhost/"));
cout << "I never show up" << endl;
// we need a channel too
AMQP::TcpChannel channel(&connection)
I've found my problem: I wasn't using the declareQueue() method! In fact, I had to use it but specifying the following parameters (the same as I did when I created the queue manually):
AMQP::Table arguments;
arguments["x-message-ttl"] = 120 * 1000;
// declare the queue
channel.declareQueue("domoqueue", AMQP::durable + AMQP::passive, arguments).onSuccess(callback);

ALSA re-enter to callback during callback execution

My application uses ALSA with callbacks facility to play selected piece of sound. Sometimes it just hangs. I was debugging it hardly 2 days, and finally found that ALSA's callback function invoked while it is executing already. I caught this using:
void MyALSACallback()
{
std::cout << "1"; std::cout.flush();
// ... snd_pcm_writei() call ... //
// ... no any returns ... //
std::cout << "2"; std::cout.flush();
return;
}
The application hangs when i have sequence "11" printed. The "121212..." is on console while application is alive and sound is playing.
How that may happen?