Removed thread from packet writer (SMACK-123).

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@3412 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Matt Tucker 2006-02-08 23:11:21 +00:00 committed by matt
parent 9acdd912d9
commit d323d6db9c
2 changed files with 34 additions and 58 deletions

View File

@ -27,7 +27,9 @@ import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.Packet;
/** /**
* Writes packets to a XMPP server. * Writes packets to a XMPP server. Packets are sent using a dedicated thread. Packet
* interceptors can be registered to dynamically modify packets before they're actually
* sent. Packet listeners can be registered to listen for all outgoing packets.
* *
* @author Matt Tucker * @author Matt Tucker
*/ */
@ -41,8 +43,7 @@ class PacketWriter {
private List listeners = new ArrayList(); private List listeners = new ArrayList();
private boolean listenersDeleted = false; private boolean listenersDeleted = false;
private Thread listenerThread;
private LinkedList sentPackets = new LinkedList();
/** /**
* List of PacketInterceptor that will be notified when a new packet is about to be * List of PacketInterceptor that will be notified when a new packet is about to be
* sent to the server. These interceptors may modify the packet before it is being * sent to the server. These interceptors may modify the packet before it is being
@ -72,14 +73,6 @@ class PacketWriter {
writerThread.setName("Smack Packet Writer"); writerThread.setName("Smack Packet Writer");
writerThread.setDaemon(true); writerThread.setDaemon(true);
listenerThread = new Thread() {
public void run() {
processListeners();
}
};
listenerThread.setName("Smack Writer Listener Processor");
listenerThread.setDaemon(true);
// Schedule a keep-alive task to run if the feature is enabled. will write // Schedule a keep-alive task to run if the feature is enabled. will write
// out a space character each time it runs to keep the TCP/IP connection open. // out a space character each time it runs to keep the TCP/IP connection open.
int keepAliveInterval = SmackConfiguration.getKeepAliveInterval(); int keepAliveInterval = SmackConfiguration.getKeepAliveInterval();
@ -105,19 +98,20 @@ class PacketWriter {
queue.addFirst(packet); queue.addFirst(packet);
queue.notifyAll(); queue.notifyAll();
} }
// Add the sent packet to the list of sent packets. The
// PacketWriterListeners will be notified of the new packet. // Process packet writer listeners. Note that we're using the sending
synchronized(sentPackets) { // thread so it's expected that listeners are fast.
sentPackets.addFirst(packet); processListeners(packet);
sentPackets.notifyAll();
}
} }
} }
/** /**
* Registers a packet listener with this writer. The listener will be * Registers a packet listener with this writer. The listener will be
* notified of every packet that this writer sends. A packet filter determines * notified immediately after every packet this writer sends. A packet filter
* which packets will be delivered to the listener. * determines which packets will be delivered to the listener. Note that the thread
* that writes packets will be used to invoke the listeners. Therefore, each
* packet listener should complete all operations quickly or use a different
* thread for processing.
* *
* @param packetListener the packet listener to notify of sent packets. * @param packetListener the packet listener to notify of sent packets.
* @param packetFilter the packet filter to use. * @param packetFilter the packet filter to use.
@ -199,7 +193,6 @@ class PacketWriter {
*/ */
public void startup() { public void startup() {
writerThread.start(); writerThread.start();
listenerThread.start();
} }
void setWriter(Writer writer) { void setWriter(Writer writer) {
@ -274,46 +267,26 @@ class PacketWriter {
/** /**
* Process listeners. * Process listeners.
*/ */
private void processListeners() { private void processListeners(Packet packet) {
while (!done) { // Clean up null entries in the listeners list if the flag is set. List
Packet sentPacket; // removes are done seperately so that the main notification process doesn't
// Wait until a new packet has been sent // need to synchronize on the list.
synchronized (sentPackets) { synchronized (listeners) {
while (!done && sentPackets.size() == 0) { if (listenersDeleted) {
try { for (int i=listeners.size()-1; i>=0; i--) {
sentPackets.wait(2000); if (listeners.get(i) == null) {
listeners.remove(i);
} }
catch (InterruptedException ie) { }
}
if (sentPackets.size() > 0) {
sentPacket = (Packet)sentPackets.removeLast();
}
else {
sentPacket = null;
} }
listenersDeleted = false;
} }
if (sentPacket != null) { }
// Clean up null entries in the listeners list if the flag is set. List // Notify the listeners of the new sent packet
// removes are done seperately so that the main notification process doesn't int size = listeners.size();
// need to synchronize on the list. for (int i=0; i<size; i++) {
synchronized (listeners) { ListenerWrapper listenerWrapper = (ListenerWrapper)listeners.get(i);
if (listenersDeleted) { if (listenerWrapper != null) {
for (int i=listeners.size()-1; i>=0; i--) { listenerWrapper.notifyListener(packet);
if (listeners.get(i) == null) {
listeners.remove(i);
}
}
listenersDeleted = false;
}
}
// Notify the listeners of the new sent packet
int size = listeners.size();
for (int i=0; i<size; i++) {
ListenerWrapper listenerWrapper = (ListenerWrapper)listeners.get(i);
if (listenerWrapper != null) {
listenerWrapper.notifyListener(sentPacket);
}
}
} }
} }
} }

View File

@ -730,7 +730,10 @@ public class XMPPConnection {
/** /**
* Registers a packet listener with this connection. The listener will be * Registers a packet listener with this connection. The listener will be
* notified of every packet that this connection sends. A packet filter determines * notified of every packet that this connection sends. A packet filter determines
* which packets will be delivered to the listener. * which packets will be delivered to the listener. Note that the thread
* that writes packets will be used to invoke the listeners. Therefore, each
* packet listener should complete all operations quickly or use a different
* thread for processing.
* *
* @param packetListener the packet listener to notify of sent packets. * @param packetListener the packet listener to notify of sent packets.
* @param packetFilter the packet filter to use. * @param packetFilter the packet filter to use.