I have dynamically allocated memory and stored it in a struct epoll_event which was then registered to a socket for epoll to monitor. There are times that I need to close this socket before the event has triggered. If I close the socket, the event and dynamically allocated memory is lost. Is there a way to retrieve it from epoll?
I have found a solution to my problem. If you are monitoring for EPOLLRDHUP, you can call shutdown(soc, SHUT_RDWR). This will trigger your socket and allow your handler to clean up. It would be nice to be able to trigger a socket without shutting down the connection, but I do not think that is possible.
Related
I am connecting to a server as a client using TCPSocket. The main point is to keep connection open and send there or receive from there messages as soon as they arrive.
There are no problems with sending messages, but doing socket.recv(n) in main thread when server has nothing to respond with, makes client's main thread to pause while waiting for data.
What is the good practice to work with persistent connections in Ruby to prevent main thread blocking?
Let's suppose that extra thread should be used. Where to insert this thread initialization in Rails app? Make a worker process?
Receiving data on a dedicated thread is certainly possible. But also consider using IO#select or IO#read_nonblock. (TCPSocket is a subclass of IO.) If you are waiting for data to come from any one of several sockets, IO#select would be ideal. If you are doing some other processing on the main thread, but also need to remain responsive to input coming in from a socket, you can call IO#read_nonblock at intervals.
I'm putting a system that monitors a few sensors and based on them it turns a few lights on/off.
For further data analysis we also want to send that data to a central server, so we've added a Wifi shield. Keep in mind that the system should be fully functional if there's no network. So what I've done is monitor the network status in the loop() and connect again if it goes down.
Now, the problem is that Wifi.begin() blocks execution until is either connected or throws an error. This is not acceptable since during that time the system would be unresponsive.
I've looked into using threads in Arduino, for example here, but then this shows up in the Limitations:
One of the major potential problems with this library is the fact that
a single Thread that gets hung will lock the entire system up, since
the next Thread can’t be called until the current one finishes its
loop() function.
So, anyone has any pointers, ideas or experience?
Thanks,
Juan
You could create a timer interrupt that when expires kills the thread with the stalled blocking function.
Actually you may want to use an Interrupt such as Timer1 library to perform the critical updates. That way you don't need to worry about blocking code, anywhere.
I am currently building an App using CocoaAsyncSocket. I connect to a TCP server and read/write some data.
I create the socket using
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
When data is received, I use FMDB to save it into a database. Everything works fine, until I send the App to Background (using Homebutton), and then resuming to it. The UI is frozen and not responsive, the Debugger shows, that it is waiting at semaphore_wait_trap.
Don't use the main queue as an argument to the delegateQueue parameter. Use one of the global concurrent queues or a serial/parallel queue you create yourself.
Update: I just looked at the implementation for GCDAsyncSocket and now realize that the delegate queue and methods are fired async to the actual read/write operations, which happen on an internal queue, so my suggestion was either irrelevant (depending on what you're actually doing in the completion methods) or, at the very least, not pertinent to the problem you're having. I think what's happening is that the internal socket(s) are being closed, as per the iOS App Programming Guide. To wit:
Be prepared to handle connection failures in your network-based
sockets. The system may tear down socket connections while your app
is suspended for any number of reasons. As long as your socket-based
code is prepared for other types of network failures, such as a lost
signal or network transition, this should not lead to any unusual
problems. When your app resumes, if it encounters a failure upon
using a socket, simply reestablish the connection.
The GCDAsyncSocket class you're using has some methods which seem to be aimed at dealing with this, such as -autoDisconnectOnClosedReadStream, and I think you just need to add some code to handle the disconnection / connection re-establishment case.
Sometimes when I try to send some packets continuously( I am using the send() API ) I receive this error. Now I am not sure what should I do than. I have these questions:
1) Can I re-send again ? If yes then after how much time should I try again. Is there any particular strategy to be followed
2) Is buffer size has exceeded its limits is the only reason ?
3) Can someone please give me a better idea/code, how to handle such scenario.
Thanks.
Sambit.
From send(): "EAGAIN -- The socket is marked non-blocking and the requested operation would block." and also When the message does not fit into the send buffer of the socket, send normally blocks, unless the socket has been placed in non-blocking I/O mode. In non-blocking mode it would return EAGAIN in this case. The select(2) call may be used to determine when it is possible to send more data.
This thread has a simple example of using select() to deal with EAGAIN, and is followed by significant discussion about what sorts of surprises lurk beneath the surface.
EAGAIN is usually returned when there is no outbound buffer space left. How long to wait depends on the speed of the underlying connection. The normal way is to wait until select() or poll() tells you that the socket is available for writing. If on Linux, take a look at the select_tut(2) manpage, and of course the send(2) manpage.
You could change to blocking operation (which is the default) if you want the call to wait until there is space available. Or you could call select(2) to wait until the socket is writeable and then try again.
There is one other important consideration. If you are sending UDP packets, then keep in mind that there is no guarantee of congestion control, and if you're sending packets over the Internet you will almost certainly get packet loss if you just try sending UDP packets as fast as possible (this doesn't necessarily apply to other datagram sockets such as Unix sockets).
I'm using IOCP on UDP socket, and the UDP socket may be closed in another thread. So, how can I free Per Socket Context and Per I/O Context which associated with SOCKET safely?
When I close the socket, there will still be un-completed I/O request in kernel queue.
If I free context just when socket closed, the GetQueueCompletionStatus may failed.
Now, my question is when to free context?
I use reference counting on all of my per socket and per I/O data structures. It makes this kind of thing easy as they are deleted when their references drop to 0. For some example code which shows one way to do this you could take a look at my free IOCP framework which you can download from here.
Use a mutex to enforce mutual exclusion in a critical section of your code that will check the availability of the socket, and open it if necessary. Lock the socket to that thread, and release it appropriately when finished.
I reuse my per-socket structures. After I have received completion events for all of the read and write operations that are required for that connection, I call TransmitFile with the TF_DISCONNECT and TF_REUSE_SOCKET flags to reset the socket without having to close it. I also reset the per-connection data once the completion event for the TransmitFile call comes through.
Close the socket first. You will get error (I think it is ERROR_OPERATION_ABORTED) from GetQueuedCompletionStatus, and then it is right time to free the structure. There are no other uncompleted requests on this connection in kernel queue by then, completion packets are maintained in FIFO order, and error packet will definitely be the last one for this connection.