Add to the above question the concept of a wait/no wait indicator as a parameter to a ReadMessage function in a TCP/IP or UDP environment.
A third party function description states that:
This function is used to read a message from a queue which was defined by a previous registerforinput call. The input wait/no wait indicator will determine if this function will block on the queue specified, waiting for the data to be placed on the queue. If the nowait option is specified and no data is available a NULL pointer will be returned to the caller. When data available this function will return a pointer to the data read from the queue.
What does it mean for a function to be blocking or non-blocking?
Blocking means that execution of your code (in that thread) will stop for the duration of the call. Essentially, the function call will not return until the blocking operation is complete.
A blocking read will wait until there is data available (or a timeout, if any, expires), and then returns from the function call. A non-blocking read will (or at least should) always return immediately, but it might not return any data, if none is available at the moment.
An analogy if you'll permit me - sorry, it's late in the afternoon and I'm in the mood, if it gets down voted - ah well...
You want to get into a snazzy nightclub, but the bouncer tells you you cannot go in till someone comes out. You are effectively "blocked" on that condition. When someone comes out, you are free to go in - or some error condition such as "are those trainers?" Your night doesn't really kick off till you get in, your enjoyment is "blocked".
In a "non-blocking" scenario, you will tell the bouncer your phone number, and he will call you back when there is a free slot. So now you can do something else while waiting for someone to come out, you can start your night somewhere else and come back when called and continue there...
Sorry if that didn't help...
Take a look at this: http://www.scottklement.com/rpg/socktut/nonblocking.html
Here's some excerpts from it:
'By default, TCP sockets are in "blocking" mode. For example, when you call recv() to read from a stream, control isn't returned to your program until at least one byte of data is read from the remote site. This process of waiting for data to appear is referred to as "blocking".'
'Its possible to set a descriptor so that it is placed in "non-blocking" mode. When placed in non-blocking mode, you never wait for an operation to complete. This is an invaluable tool if you need to switch between many different connected sockets, and want to ensure that none of them cause the program to "lock up."'
Also, it's generally a good idea to try to search for an answer first (just type "blocking vs. non-blocking read" in a search engine), and then once you hit a wall there to come and ask questions that you couldn't find an answer to. The link I shared above was the second search result. Take a look at this great essay on what to do before asking questions on internet forums: http://www.catb.org/~esr/faqs/smart-questions.html#before
In your case, it means the function will not return until there actually is a message to return. It'll prevent your program from moving forward, but when it does move forward you'll have a message to work with.
If you specify nowait, a null pointer will be returned immediately if there are no messages on the queue, which allows you to process that situation.
Related
Let's say I have an array of non-blocking MPI requests initiated in a series of calls to MPI_ISEND (or MPI_IRECV). I store the request info in the array xfer_rqst. It is my understanding that when a request completes, its corresponding value in xfer_rqst will be set to MPI_REQUEST_NULL. Further, it's my understanding that if a call is made to MPI_WAITALL, it will have work to do only if some requests in xfer_rqst still have some value other than MPI_REQUEST_NULL. If I have it right, then, if all requests complete before we get to the MPI_WAITALL call, then MPI_WAITALL will be a no-op for all intents and purposes. If I am right about all this (hoo boy), then the following Fortran code should work and maybe occasionally save a useless function call:
IF (ANY(xfer_rqst /= MPI_REQUEST_NULL)) &
CALL MPI_WAITALL(num_xfers, xfer_rqst, xfer_stat, ierr)
I have actually run this several times without an issue. But still I wonder, is this code proper and safe?
It is indeed often the case that you can decide from the structure of your code that certain requests are satisfied. So you think you can skip the wait call.
And indeed you often can in the sense that your code will work. The only thing you're missing is that the wait call deallocates your request object. In other words, by skipping the wait call you have created a memory leak. If your wait call is in a region that gets iterated many times, this is a problem. (As noted in the comments, the standard actually states that the wait call is needed to guarantee completion.)
In your particular case, I think you're wrong about the null request: it's the wait call that sets the request to null. Try it: see if any requests are null before the wait call.
Reading the function description curl_multi_wakeup: enter link description here
Calling this function only guarantees to wake up the current (or the
next if there is no current) curl_multi_poll call, which means it is
possible that multiple calls to this function will wake up the same
waiting operation.
I am confused by the phrase - "the same waiting operation". How's that?
That is, suppose I have a function curl_multi_poll() in event standby mode in thread "A".
Now, for example, I call the curl_multi_wakeup() function twice from thread "B" and thread "C".
And what happens judging by this phrase:
...function will wake up the same waiting operation.
It turns out that the function curl_multi_poll - wakes up only once ?
curl_multi_wakeup is meant to be used with a pool of threads waiting on curl_multi_poll.
What the document says is that if you call curl_multi_wakeup repeatedly, it will possibly wake up only a single thread, not necessarily one thread for each call to curl_multi_wakeup.
curl_multi_poll() is a relatively new call, designed to simplify "interrupting" threads waiting on curl_multi_poll(). Here's a good explanation:
https://daniel.haxx.se/blog/2019/12/09/this-is-your-wake-up-curl/
curl_multi_poll()
[is a] function which asks libcurl to wait for activity on any of the
involved transfers – or sleep and don’t return for the next N
milliseconds.
Calling this waiting function (or using the older curl_multi_wait() or
even doing a select() or poll() call “manually”) is crucial for a
well-behaving program. It is important to let the code go to sleep
like this when there’s nothing to do and have the system wake up it up
again when it needs to do work. Failing to do this correctly, risk
having libcurl instead busy-loop somewhere and that can make your
application use 100% CPU during periods. That’s terribly unnecessary
and bad for multiple reasons.
When ... something happens and the application for example needs to
shut down immediately, users have been asking for a way to do a wake
up call.
curl_multi_wakeup() explicitly makes a curl_multi_poll() function
return immediately. It is designed to be possible to use from a
different thread.
My question
In the Interactive Brokers TWS c++ API, (or in event-driven programming in general) when is it critical to change the state/mode (this is m_state in TWS API) to a state of "acknowledgement?" Depending on the state of this variable, different class methods are called. Towards the end of the definition of one of these methods, the state is changed back to an acknowledgement state, which appears to allow messages to be received by the host. Can I change m_state to something else, and skip the acknowledgement process altogether?
Some background information for those who don't know the TWS API
(feel free to ignore this section)
Interactive Brokers' TWS C++ API has tens of thousands of lines of code, so let me try to describe what I think the essential functionality is.
My programs entry point in Main.cpp instantiates a client object, and then repeatedly calls its void TestCppClient::processMessages() method over and over again in every iteration of a while loop.
On the one hand, there are a bunch of methods that get triggered by the broker whenever the broker decides to call them, and you, as a client, may or may not take advantage of the provided information.
But on the other hand, there are a bunch of methods that get triggered by my client code. Depending on the value of m_state, a different class method is triggered. In the sample code provided by IB, that is, in my TestCppClient class, most of these functions have some helpful demonstration code provided, and more to the point of my question, most of these functions have the last line setting the value of m_state to something ending in _ACK (which, I believe, is a socket programming convention that is short for "acknowledgement.")
For example, when m_state is equal to ST_REUTERSFUNDAMENTALS, TestCppClient::processMessages()'s switch statement will trigger TestCppClient::reutersFundamentals(). The last line of this method's definition is
m_state = ST_REUTERSFUNDAMENTALS_ACK;
The next time void TestCppClient::processMessages() is triggered, (and it gets triggered all the time by the while loop, if you recall) the switch statement is skipped due to there only being a break statement:
...
case ST_REUTERSFUNDAMENTALS:
reutersFundamentals();
break;
case ST_REUTERSFUNDAMENTALS_ACK:
break;
...
This switch statement code makes up the majority of the code in this function's definition, but there is a little at the end outside of the switch statement. The only code that runs in TestCppClient::procesMessages() in this case is at the very end, which is
m_pReader->checkClient();
m_osSignal.waitForSignal();
m_pReader->processMsgs();
These lines apparently handle some low-level socket programming stuff.
Reiterating my question
So, if I didn't change the state to an acknowledgement state, these last three lines wouldn't run. But would that be a bad thing? Does anyone have experience with this? Any anecdotal pieces of information?
The TestCppClient example is fairly complicated as IB/C++ applications go, but those three lines are important. m_pReader is an instance of the EReader class, which reads incoming data and produces messages. Because it runs in its own thread, it needs special handling.
The checkClient function tells the EReader to package incoming data into an EMessage and store the message in the message queue. But the application can't access the queue until the waitForSignal function returns. Afterward, processMsgs reads the EMessage and calls the appropriate callback function.
Dealing with the EReader is a pain, but once you get an application working, you can copy and paste the code into further applications.
Yes you can just remove all m_state switches. you may notice the ST_ part (start) of m_state are ultimately trigged in function nextValidId(). In processMessages() function the ST conditionals call client functions and afterwards, m_state is flipped to ACK to then break - only relevant part, if you were to use processMessages() for processing msg que is m_osSignal.waitForSignal(); errno = 0; m_pReader->processMsgs(); which can be called outside of processMessages(). Basically when using any function you may comment out all m_state switches. But still need to waitforsignal,process messages as needed. Seems m_state was just convenient for the testbed and quickly testing functions only commenting/uncommenting what you wanted to play with.
I have a tcp::socket for reading and writing data. There is a read loop made up by chaining async_read_some() and the handler on_data_read() that calls async_read_some() again after dealing with the data read. A relevant shared_ptr<tcp::socket> is passed along the loop. The loop ends when on_data_read() is called with a non-success error_code such as asio::error::eof, in which case async_read_some() is not called.
There may also be asynchronous writes on the socket, which is done by repeated calls to async_write_some() until all data is written. That is, the handler on_data_written() for async_write_some() calls async_write_some() again if the data is only partially written. The relevant shared_ptr<tcp::socket> is also passed along the call-chain.
Now, I want to close the socket in a safe manner. Specifically, I want to force the asynchronous read to finish early with a non-success error code to ends the read loop. If there is no pending write call-chain, the only shared_ptr<tcp::socket> (the one passed along the read loop) gets destroyed with its managed tcp::socket closed and destroyed. If there is a pending write call-chain, it continues until all data is written. At the time the write call-chain goes to its end, the last shared_ptr<tcp::socket> (the one passed along the write call-chain) gets destroyed. This procedure is safe in the sense that the socket is closed after pending writes, if any.
The problem is
how can I force the asynchronous socket read to finish with a non-success error code?
I've checked the linger option. But it won't work since I'm using chained-up async_write_some() instead of a single async_write(). So, the socket may be closed while on_data_written() is being called. cancel() and close() won't work either, since they interrupt not only the read loop but also the write call-chain. And although shutdown() can be applied to the read loop only, it prevents future async_read_some() calls only, and has no effect on what is already done. I've worked out a workaround solution. That is, call cancel(), but have on_data_written() ignore the the error code caused by cancel() and continue the write call-chain. I'm not satisfied with this solution (see the remarks section here). I'm wondering if there is a more direct and elegant way to achieve what I want, or the whole design is just flawed?
In my opinion you've summed it up pretty nicely.
You cannot really do better than fullblown cancel. Indeed you may resume any canceled writes.
I don't think there is anything more elegant. I would not say the design is flawed, but you might want to consider not actually canceling pending operations, but instead just keeping a flag to indicate whether a "logical read cancel" is pending and prevent chaining more reads in that case
When you used shutdown.. eg.. socket.shutdown did you use the shutdown_both?
(boost::asio::ip::tcp::socket::shutdown_both, ec)
The shutdown_both option. That should handle read and write closures.
socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both, errorcode);
if (errorcode)
{
cerr << "socket.shutdown error: " << errorcode.message() << endl;
}
Also.. If you have the io_service handle. you can call io_service.stop() as a last resort which will shutdown all operations.
Shutdown the socket for input. That will cause all pending reads to encounter end of stream and return accordingly.
And although shutdown() can be applied to the read loop only, it prevents future async_read_some() calls only, and has no effect on what is already done.
I don't know where you got this misinformation from. I don't even know what it means. Shutdown applies to the socket, not a read loop.
I'm using a third party library which has a blocking function, that is, it won't return until it's done; I can set a timeout for that call.
Problem is, that function puts the library in a certain state. As soon as it enters that state, I need to do something from my own code. My first solution was to do that in a separate thread:
void LibraryWrapper::DoTheMagic(){
//...
boost::thread EnteredFooStateNotifier( &LibraryWrapper::EnterFooState, this );
::LibraryBlockingFunction( timeout_ );
//...
}
void LibraryWrapper::EnterFooState(){
::Sleep( 50 ); //Ensure ::LibraryBlockingFunction is called first
//Do the stuff
}
Quite nasty, isn't it? I had to put the Sleep call because ::LibraryBlockingFunction must definitely be called before the stuff I do below, or everything will fail. But waiting 50 milliseconds is quite a poor guarantee, and I can't wait more because this particular task needs to be done as fast as possible.
Isn't there a better way to do this? Consider that I don't have access to the Library's code. Boost solutions are welcome.
UPDATE: Like one of the answers says, the library API is ill-defined. I sent an e-mail to the developers explaining the problem and suggesting a solution (i.e. making the call non-blocking and sending an event to a registered callback notifying the state change). In the meantime, I set a timeout high enough to ensure stuff X is done, and set a delay high enough before doing the post-call work to ensure the library function was called. It's not deterministic, but works most of the time.
Would using boost future clarify this code? To use an example from the boost future documentation:
int calculate_the_answer_to_life_the_universe_and_everything()
{
return 42;
}
boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything);
boost::unique_future<int> fi=pt.get_future();
boost::thread task(boost::move(pt));
// In your example, now would be the time to do the post-call work.
fi.wait(); // wait for it to finish
Although you will still presumably need a bit of a delay in order to ensure that your function call has happened (this bit of your problem seems rather ill-defined - is there any way you can establish deterministically when it is safe to execute the post-call state change?).
The problem as I understand it is that you need to do this:
Enter a blocking call
After you have entered the blocking call but before it completes, you need to do something else
You need to have finished #2 before the blocking call returns
From a purely C++ standpoint, there's no way you can accomish this in a deterministic way. That is without understanding the details of the library you're using.
But I noticed your timeout value. That might provide a loophole, maybe.
What if you:
Enter the blocking call with a timeout of zero, so that it returns immediately
Do you other stuff, either in the same thread or synchronized with the main thread. Perhaps using a barrier.
After #2 is verified to be done, enter the blocking call again, with the normal non-zero timeout.
This will only work if the library's state will change if you enter the blocking call with a zero timeout.