Update of /cvsroot/freenet/freenet/src/freenet/transport
In directory sc8-pr-cvs1:/tmp/cvs-serv4026/src/freenet/transport
Modified Files:
ReadSelectorLoop.java AbstractSelectorLoop.java
Log Message:
Create a class for the waitersQueue, relieves the enqueuer of a couple synchronize().
Decrease the scope of the locks in processWaiters.
Index: ReadSelectorLoop.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/transport/ReadSelectorLoop.java,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -w -r1.60 -r1.61
--- ReadSelectorLoop.java 25 Oct 2003 08:04:29 -0000 1.60
+++ ReadSelectorLoop.java 29 Oct 2003 10:34:56 -0000 1.61
@@ -145,8 +145,7 @@
} else {
if(logDebug)
Core.logger.log(this, "Maintenance process returned -1
but not registered on selector, queuing for unregistration", Logger.DEBUG);
- unregisterWaiters.add(new ChannelAttachmentPair
- (chan, current));
+ unregisterWaiters.add(new ChannelAttachmentPair(chan,
current));
}
queueClose((SocketChannel)chan,current);
} else if (status == 0) {
@@ -158,8 +157,7 @@
} else {
if(logDebug)
Core.logger.log(this, "Maintenance process returned 0 but
not registered on selector, queuing for unregistration", Logger.DEBUG);
- unregisterWaiters.add(new ChannelAttachmentPair
- (chan, current));
+ unregisterWaiters.add(new ChannelAttachmentPair(chan,
current));
}
synchronized(dontReregister) {
dontReregister.add(chan);
Index: AbstractSelectorLoop.java
===================================================================
RCS file: /cvsroot/freenet/freenet/src/freenet/transport/AbstractSelectorLoop.java,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -w -r1.85 -r1.86
--- AbstractSelectorLoop.java 28 Oct 2003 03:02:50 -0000 1.85
+++ AbstractSelectorLoop.java 29 Oct 2003 10:34:56 -0000 1.86
@@ -21,7 +21,10 @@
*/
public abstract class AbstractSelectorLoop implements SelectorLoop{
- protected LinkedList registerWaiters, unregisterWaiters, delayedWaiters;
+ //protected LinkedList registerWaiters, unregisterWaiters, delayedWaiters;
+ protected ChannelAttachmentPairQueue registerWaiters= new
ChannelAttachmentPairQueue();
+ protected ChannelAttachmentPairQueue unregisterWaiters= new
ChannelAttachmentPairQueue();
+ protected ChannelAttachmentPairQueue delayedWaiters= new
ChannelAttachmentPairQueue();
protected Selector sel;
protected Set currentSet;
@@ -106,9 +109,6 @@
public AbstractSelectorLoop() throws IOException{
sel = Selector.open();
- registerWaiters = new LinkedList();
- unregisterWaiters = new LinkedList();
- delayedWaiters = new LinkedList();
stop = false;
cleanupNeeded=false;
timeout = TIMEOUT;
@@ -146,6 +146,38 @@
attachment.toString());
}
}
+ /**
+ * a synchronized queue that accepts single or bunched ChannelAttachmentPair:s
and returns a list containing all items queued
+ */
+ protected class ChannelAttachmentPairQueue {
+ private LinkedList queue = new LinkedList();
+ private Object queueLock = new Object();
+
+ //Adds the ChannelAttachmentPair to the queue
+ void add(ChannelAttachmentPair cap) {
+ synchronized(queueLock){
+ queue.add(cap);
+ }
+ }
+ void addAll(LinkedList l) {
+ synchronized(queueLock){
+ queue.addAll(l);
+ }
+ }
+ //Returns and flushes the current queue
+ //If no items is queued then null is returned
+ LinkedList get() {
+ //Avoid locking and allocation if we dont have any items queued
+ //There shuldn't be any real drawback with keeping this check
unsynchronized
+ if(queue.size()==0)
+ return null;
+ synchronized(queueLock){
+ LinkedList retval = queue;
+ queue = new LinkedList();
+ return retval;
+ }
+ }
+ }
protected final class DelayedChannelAttachmentPair extends
ChannelAttachmentPair {
public final long registerTime;
@@ -186,9 +218,8 @@
}
//minimize the number of exceptions in the select thread, check early
if (ch.isBlocking()) throw new IllegalBlockingModeException();
- synchronized(registerWaiters) {
registerWaiters.add(new ChannelAttachmentPair(ch, attachment));
- }
+
}
public final void register(Socket sock, Object attachment) throws
IllegalBlockingModeException {
@@ -201,19 +232,15 @@
if(logDebug)
Core.logger.log(this, "Unregistering "+chan,
new Exception("debug"),
Logger.DEBUG);
- synchronized(unregisterWaiters) {
unregisterWaiters.add(new ChannelAttachmentPair(chan,null));
}
- }
public final void unregister(Object attachment) {
if(logDebug)
Core.logger.log(this, "Unregistering "+attachment,
new Exception("debug"),
Logger.DEBUG);
- synchronized(unregisterWaiters) {
unregisterWaiters.add(new
ChannelAttachmentPair(null,attachment));
}
- }
public final boolean isOpen() {
return sel.isOpen();
@@ -240,40 +267,40 @@
*/
protected final void processWaiters() {
- while (delayedWaiters.size() > 0) {
+ LinkedList waitersToProcess = delayedWaiters.get();
+ while (waitersToProcess != null && waitersToProcess.size() > 0) {
DelayedChannelAttachmentPair current =
- (DelayedChannelAttachmentPair)
delayedWaiters.removeFirst();
+ (DelayedChannelAttachmentPair)
waitersToProcess.removeFirst();
if (System.currentTimeMillis() >= current.registerTime)
registerWaiters.add(current);
else
- delayedWaiters.add(current);
+ delayedWaiters.add(current); //TODO: Would it be
better to avoid a bunch of finegrained put():s by using an putAll() instead
}
//TODO: find a way to get the try's out of the loop
//first add
LinkedList notRegistered = new LinkedList();
- synchronized(registerWaiters) {
- while(registerWaiters.size() >0) {
- ChannelAttachmentPair current =
(ChannelAttachmentPair)registerWaiters.removeFirst();
+ waitersToProcess = registerWaiters.get();
+ while (waitersToProcess != null && waitersToProcess.size() > 0) {
+ ChannelAttachmentPair current = (ChannelAttachmentPair)
waitersToProcess.removeFirst();
if (myKeyOps() == SelectionKey.OP_ACCEPT) //this is a
server socket
try{
current.channel.register(sel,
SelectionKey.OP_ACCEPT, current.attachment);
- }catch(ClosedChannelException e) {continue;}
- else if (myKeyOps() == SelectionKey.OP_READ) {
+ } catch (ClosedChannelException e) {
+ continue;
+ } else if (myKeyOps() == SelectionKey.OP_READ) {
//a reader, writers get registered on the fly
- if(!current.channel.isOpen()) continue;
+ if (!current.channel.isOpen())
+ continue;
if(shouldRegister(current)) {
try {
- if
(current.channel.keyFor(sel) ==null ||
-
!current.channel.keyFor(sel).isValid()) {
-
current.channel.register(sel, SelectionKey.OP_READ,
-
current.attachment);
+ if (current.channel.keyFor(sel) ==
null || !current.channel.keyFor(sel).isValid()) {
+ current.channel.register(sel,
SelectionKey.OP_READ, current.attachment);
((NIOCallback)current.attachment).registered();
}
} catch(ClosedChannelException e) {
if(current.attachment
instanceof NIOCallback)
-
((NIOCallback)current.attachment).
- unregistered();
+ ((NIOCallback)
current.attachment).unregistered();
try {
queueClose(current);
} catch
(IllegalArgumentException x) {
@@ -286,49 +313,45 @@
} catch (CancelledKeyException e) {
//do nothing?
if (logDebug)
-
Core.logger.log(this,"cought "+e,Logger.DEBUG);
+ Core.logger.log(this, "caught
" + e, Logger.DEBUG);
}
} else {
notRegistered.add(current);
}
}
}
- while(!notRegistered.isEmpty()) {
- ChannelAttachmentPair current =
(ChannelAttachmentPair)notRegistered.removeFirst();
- registerWaiters.add(current);
- }
- }
+ registerWaiters.addAll(notRegistered);
//then remove
- synchronized(unregisterWaiters) {
- while (unregisterWaiters.size() >0) {
+
+ waitersToProcess = unregisterWaiters.get();
+ while (waitersToProcess != null && waitersToProcess.size() > 0) {
ChannelAttachmentPair current;
try {
- current =
-
(ChannelAttachmentPair)unregisterWaiters.removeFirst();
+ current = (ChannelAttachmentPair)
waitersToProcess.removeFirst();
} catch (NoSuchElementException e) {
- Core.logger.log(this, "Parallel removal of elements in
"+this+
- "?: "+e, e,
Logger.ERROR);
+ Core.logger.log(this, "Parallel removal of elements in
" + this +"?: " + e, e, Logger.ERROR);
break;
}
if (current.channel!=null) {
//we have a channel
SelectionKey k = current.channel.keyFor(sel);
- if(k != null) k.cancel();
+ if (k != null)
+ k.cancel();
}
// Not used by WSL, so we don't need to tell it
else if (current.attachment!=null) { //we have only the
attachment
Iterator i = sel.keys().iterator();
while(i.hasNext()) {
SelectionKey curKey = (SelectionKey)i.next();
- if(curKey == null) continue;
- if(!curKey.isValid()) continue;
+ if (curKey == null)
+ continue;
+ if (!curKey.isValid())
+ continue;
Object attachment = curKey.attachment();
if(attachment == null) {
if(logDebug)
- Core.logger.log(this, "Key
"+curKey+" has null "+
-
"attachment unregistering "+
-
current, Logger.ERROR);
+ Core.logger.log(this, "Key " +
curKey + " has null " + "attachment unregistering " + current, Logger.ERROR);
curKey.cancel();
} else if
(attachment.equals(current.attachment)) {
curKey.cancel();
@@ -339,7 +362,8 @@
if (current.attachment!=null)
try{
((NIOCallback)current.attachment).unregistered();
- }catch(ClassCastException e) {continue;}
+ } catch (ClassCastException e) {
+ continue;
}
}
}
_______________________________________________
cvs mailing list
[EMAIL PROTECTED]
http://dodo.freenetproject.org/cgi-bin/mailman/listinfo/cvs