boost::asio::io_service::run() is not exiting when i call boost::asio::io_serive::stop() - sockets

Hi I having written one simple application which uses the asynchronous socket functions. I am facing some problems while closing the socket.
I am using 5 second timer before calling the async_connect on the socket. In some cases the connection is not happening and timer expires. When timer is expired I am closing the socket tcp_socket.close(). But the thing is my connection callback handler is not at all called with the boost::asio::error::operation_aborted error when i tried to cancel instead of close. The same thing is happening for the next all the async connection invokes.
Eventhough I am closing the tcp socket and destroying the client_session object join() call on the created thread is not coming out means io_service::run() is still running not exiting...:-( I don't know why this is happening... tried lot of other ways still facing the same problem.
I am not getting what is the problem, all suggestions and solutions will be appreciated.
My real code some what look like this.
class client_session
{
public:
client_session(boost::asio::io_service& io_service_ )tcp_socekt_(io_service_),
timer_(io_service_)
{
}
~client_session()
{
tcp_socket_.close();
}
void OnTimerExpired(const boost::system::error_code& err)
{
if( err ) tcp_socket_.close();
}
//Its just for example this will be called from upper layer of my module. giving some information about the server.
void connect()
{
//Here am starting the timer
timer_.expires_from_now(boost::posix_time::seconds(2));
timer_.async_wait(boost::bind(&OutgoingSession::OnTimerExpiry, this,PLACEHLDRS::error));
.......
tcp_socket_.async_connect(iterator->endpoint(), boost::bind( &OutgoingSession::handle_connect, this, _1, iterator));
......
}
void OnConnect(const boost::system::error_code& err)
{
//Cancelling the timer
timer_.cancel();
.....
//Register for write to send the request to server
......
}
private:
tcp::socket tcp_socket_;
deadline_timer timer_;
}
void main()
{
boost::asio::io_service tcp_io_service;
boost::asio::io_service::work tcp_work(tcp_io_service);
boost::thread* worker = new boost::thread(&boost::asio::io_service::run,&tcp_io_service);
client_session* csession = new client_session(tcp_io_service);
csession->connect();
sleep(10);
tcp_io_service.stop();
delete csession;
worker.join(); //Here it not coming out of join because io_service::run() is not exited yet.
cout<<"Termination successfull"<<endl;
}

There seem to be a couple of different things wrong with the posted code. I would suggest starting with smaller steps i.e. along the lines of
start and stop asio worker thread cleanly ( see explanation below )
add code to start timer: handle OnTimerExpired correctly, check error code
add in code for async_connect: when connect handler is called, cancel timer and check error code.
add in other asynchronous operations, etc.
For one, when you cancel the timer in the connect handler, the OnTimerExpired handler will be invoked with boost::asio::operation_aborted and then you close the socket, which is probably not what you want to do.
Further, you give the io_service work, yet still call stop. Generally if you give the io_service work, you want to stop the execution thread by removing the work (e.g. This can be accomplished by means of storing work in a smart pointer and resetting it) and letting the currently started asynchronous operations finish cleanly.

Related

Stopping a `CallbackInstrument` prior to setting `AVAudioSession.setActive(false)`

In attempt to pause my signal chain when a user puts the app into the background, or is interrupted by a phone call, I am trying to handle the interruption by stopping all playing nodes and setting the AVAudioSession().setActive(false) as per convention.
It seems fine to call stop() on all nodes except CallbackInstrument, which crashes at line 231 of DSPBase.cpp in *CAudioKitEX from the AudioKitEX repo :
void DSPBase::processOrBypass(AUAudioFrameCount frameCount, AUAudioFrameCount bufferOffset) {
if (isStarted) {
process(FrameRange{bufferOffset, frameCount});
} else {
// Advance all ramps.
stepRampsBy(frameCount);
// Copy input to output.
if (inputBufferLists.size() and !bCanProcessInPlace) {
for (int channel=0; channel< channelCount; ++channel) {
auto input = (const float *)inputBufferLists[0]->mBuffers[channel].mData + bufferOffset;
auto output = (float *)outputBufferList->mBuffers[channel].mData + bufferOffset;
std::copy(input, input+frameCount, output);
}
}
// Generators should be silent.
if (inputBufferLists.empty()) {
zeroOutput(frameCount, bufferOffset);
}
}
}
My CallbackInstrument is attached to a Sequencer as a discrete track. The crash occurs when the sequencer is playing and the app goes into the background, which I then call a method to stop all current sequencers, stop all active nodes prior to calling AVAudioSession.setSession(false).
I would simply ignore this and/or not stop CallbackInstrument however, by not attempting to stop or reset the CallbackInstrument node, AVAudioSession catches an error:
AVAudioSession_iOS.mm:1271 Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
Error seting audio session false:Error Domain=NSOSStatusErrorDomain Code=560030580 "(null)"
Error code=560030580 refers to AVAudioSessionErrorCodeIsBusy as stated here
Question:
If stopping a Sequencer with a CallbackInstrument does not in fact stop rendering audio/midi from the callback, how do we safely stop a signal chain with a CallbackInstrument in order to prepare for AVAudioSession.setActive(false)?
I have an example repo of the issue which can be found here.
Nicely presented question by the way :)
Seems like doing it this way does not guarantee that the audioBufferList in process or bypass is populated, while it does report that the size() == 1, its pointer to audioBuferList[0] is nill...
Possibly there should be an additional check for this?
However, if instead of calling stop() on every node in your AudioManager.sleep() if you call engine.stop()
and conversely self.start() in your AudioManager.wake() instead of start on all your nodes... This avoids your error and should stop/start all nodes in the process.

How to capture command line input from Vert.x

Env: Mac OS 12.1, JDK 17, Vert.x 4.2.4
Question: how to capture command line input from a verticle? Tried so far following in the public void start(Promise<Void> startPromise) throws Exception method:
getVertx().createSharedWorkerExecutor("sys-in").executeBlocking(promise -> {
try (final BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
String line;
int count = 0;
do {
System.out.print("message to MC: ");
line = br.readLine();
count++;
//doSth(line); // e.g. send line over multicast
} while (count < 3);
} catch (Throwable t) {
// log.info("<start> ", t);
} finally {
// bye(); // send a final message and close vertx
promise.complete();
}
});
This will start, get 3 nulls from br, and exit. Also tried a separated ExecutorService, in vain. Couldn't find any help in Vert.x doc either. Any hints are appreciated:
aware of the warnings of Vert.x when doing blocking stuff
Vert.x might not meant to be used this way, but would be cool if it (reading from command line) can be done with the same toolkit
I understand what you are trying to accomplish, but the problem is that that goes against fundamentals of verticles concept. Waiting for user input is potentially infinitely blocking operation i.e. there is no guarantee user will ever input the values. In that case, you are left with the verticle that is hung forever, spending resources and stuck in one spot. Multiply this if you are using worker verticles and you might have serious problems with the app. This issue is also emphasized here: https://vertx.io/docs/vertx-core/java/#blocking_code (under Warning).
In the link provided you can also find a suggested solution with a separate thread solution. Non-vertx thread won't mind being blocked and when the user input is provided can inform the vertx part of the application via the event bus that the user input dependent code can now be executed.
This might not be the solution you had in mind since it's not pure vertx, but have in mind that vert.x is just another tool, and that tool is not a good fit for what you are trying to accomplish here. However, it can be paired well with plain Java and it won't mind.

How can i clear QLocalSocket?

I've a problem in clearing the QLocalSocket.
Now I'm sending & receiving the image data through QLocalServer/QLocalSocket.
But in receiving program, memory increases heavily because of piled image data in memory.
so, I want to clean up the socket when the data was read.
but it seems there is no function in QLocalSocket reference.
How can I clear the socket?
It looks like the only way to avoid this behaviour is to close socket (not named pipe server) and to open it again once you have received enough data. Also please note, that just closing socket and using the same instance (i.e socket created on stack) caused me a lot of troubles.
I am doing this next way:
On the sender side you have:
dataSocket->write((char*)data, sizeof(data));
dataSocket->disconnectFromServer();
and on the client side:
void LocalSocketClient::requestNewFrame()
{
if (socket) {
socket->disconnect();
socket->deleteLater();
}
socket = new QLocalSocket();
dataStream.setDevice(socket);
connect(socket, &QLocalSocket::disconnected, this, &LocalSocketClient::requestNewFrame);
connect(socket, &QLocalSocket::readyRead, this, &LocalSocketClient::readSocket);
socket->connectToServer(NAMED_PIPE_NAME, QIODevice::ReadOnly);
}
void LocalSocketClient::readSocket()
{
if(dataStream.readRawData((char*)&currentFrame, sizeof(currentFrame)) > 0) {
}
}
where currentFrame is predefined known struct of your data.
This is not the most elegant solution as for me, I am still investigating how to avoid infinite new/deleteLater operations. But without them I was getting random writing errors on the sender side (looks like Qt event loop was deleting socket handle once it was closed and not deleted messing up private data of the socket)

Close sockets in IOCP (close some sockets in IOCP)

There are sockets in IOCP ..group A,B
A,B are working for receiving data.
But when I close sockets in group A like below.
shutdown...
closesocket...
Sockets in group B seems like corrupted and stopped working.
If anyone has experienced similar symptom.
Give me some advice.
I solved my problem. Problem is worker threads terminated unintentionally.
My previous code like below
while (GetQuededCompletionStatus...)
{
// Do io related works
}
Problem is 'GetQueuedCompiletionStatus' function returns IO status TRUE/FALSE
When socket closed It returns FALSE. So entire while loop exited and thread closed.
This fixed like below
while (1)
{
BOOL iostatus = GetQueuedCompletionStatus...
if (iostatus==TRUE)
{
// Do IO works
}
}
Maybe this skeleton is basic IOCP worker thread loop

SQLConnection Pooling - Handling InvalidOperationExceptions

I am designing a Highly Concurrent CCR Application in which it is imperative that I DO NOT Block or Send to sleep a Thread.
I am hitting SQLConnection Pool issues - Specifically getting InvalidOperationExceptions when trying to call SqlConnection.Open
I can potentially retry a hand full of times, but this isn't really solving the problem.
The ideal solution for me would be a method of periodically re-checking the connection for availablity that doesn't require a thread being tied up
Any ideas?
[Update]
Here is a related problem/solution posted at another forum
The solution requires a manually managed connection pool. I'd rather have a solution which is more dynamic i.e. kicks in when needed
Harry, I've run into this as well, also whilst using the CCR. My experience was that having completely decoupled my dispatcher threads from blocking on any I/O, I could consume and process work items much faster than the SqlConnection pool could cope with. Once the maximum-pool-limit was hit, I ran into the sort of errors you are seeing.
The simplest solution is to pre-allocate a number of non-pooled asynchronous SqlConnection objects and post them to some central Port<SqlConnection> object. Then whenever you need to execute a command, do so within an iterator with something like this:
public IEnumerator<ITask> Execute(SqlCommand someCmd)
{
// Assume that 'connPort' has been posted with some open
// connection objects.
try
{
// Wait for a connection to become available and assign
// it to the command.
yield return connPort.Receive(item => someCmd.Connection = item);
// Wait for the async command to complete.
var iarPort = new Port<IAsyncResult>();
var iar = someCmd.BeginExecuteNonQuery(iarPort.Post, null);
yield return iarPort.Receive();
// Process the response.
var rc = someCmd.EndExecuteNonQuery(iar);
// ...
}
finally
{
// Put the connection back in the 'connPort' pool
// when we're done.
if (someCmd.Connection != null)
connPort.Post(someCmd.Connection);
}
}
The nice thing about using the Ccr is that it is trivial to add the following the features to this basic piece of code.
Timeout - just make the initial receive (for an available connection), a 'Choice' with a timeout port.
Adjust the pool size dynamically. To increase the size of the pool, just post a new open SqlConnection to 'connPort'. To decrease the size of the pool, yield a receive on the connPort, and then close the received connection and throw it away.
Yes, connections are kept open and out of the connection pool. In the above example, the port is the pool.