Quantcast
Channel: Ignite Realtime: Message List
Viewing all articles
Browse latest Browse all 12162

Racecondition in PacketWriter

$
0
0

Hello,

 

Context

We are developing an application with Smack 3.4.1.

In this application we have sevaral XMMPconnections,

that are used by many threads to send packets. (An estimated total 300.000 packets a minute. )

 

We think that we have encoutered possible racecondition in

org.jivesoftware.smack.PacketWriter

 

Scenario

A XMPPConncetion creates a PacketWriter.

The PacketWriter:

-> Uses an ArrayBlocklingQueue to manage the packets that need to be written (with a max size of 500).

-> starts a thread "Smack Packet Writer (" + connection.connectionCounterValue + ") ".

 

This thread use the method

org.jivesoftware.smack.PacketWriter.nextPacket()

to get the next packet.

/**     * Returns the next available packet from the queue for writing.     *     * @return the next packet for writing.     */    private Packet nextPacket() {        Packet packet = null;        // Wait until there's a packet or we're done.        while (!done && (packet = queue.poll()) == null) {            try{                synchronized (queue) {                    queue.wait();                }            }            catch (InterruptedException ie) {                // Do nothing            }        }        return packet;   }

 

Other threads can use

org.jivesoftware.smack.PacketWriter.sendPacket(Packet)

(through to sendPacket(packet) method of XMPPConncection) to add packages to the queue.

 

/**     * Sends the specified packet to the server.     *     * @param packet the packet to send.     */    publicvoid sendPacket(Packet packet) {        if (!done) {            // Invoke interceptors for the new packet that is about to be sent. Interceptors            // may modify the content of the packet.            connection.firePacketInterceptors(packet);              try{                queue.put(packet);            }            catch (InterruptedException ie) {                log.log(Level.SEVERE, "Failed to queue packet to send to server: " + packet.toString(), ie);                return;            }            synchronized (queue) {                queue.notifyAll();            }              // Process packet writer listeners. Note that we're using the sending            // thread so it's expected that listeners are fast.            connection.firePacketSendingListeners(packet);        }    }

 

Now, i think the following scenario is possible :

-> the queue.poll() method in nextpacket() returns null

-> context switches happen and the queue gets 500 queue.put(packet) in sendPacket(packet) from different threads

-> the 501the queue.put(packet) blocks ( the size of the queue is 500)

-> nextpacket() continues and starts waiting on a notification

-> a notification never happens because all the following queue.put(packet) are blocked...

 

We have encoutered a waiting smack writer (*) thread while we can verify , with a heap dump, that the queue in this writer thread is full...

 

Possible solution

In:

org.jivesoftware.smack.PacketWriter.nextPacket()

1. use a timed wait to ait for a notification

or (maybe better)

2. Use ArrayBlockingQueue.take() instead of ArrayBlockingQueue.poll()

 

 

I am relativly new to multi threading .

I hope i am on the correct path to pinpoint a possible bug and a solution.

If not, please correct me. ;-)

 

regards,

 

m_dh


Viewing all articles
Browse latest Browse all 12162

Trending Articles