Fixes #335836 (Race when updating SelectChannelEndPoint._dispatched)

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2714 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Simone Bordet 2011-01-31 12:28:38 +00:00
parent caff41bebb
commit 813d652e41
2 changed files with 45 additions and 42 deletions

View File

@ -31,6 +31,7 @@ jetty-7.3.0-SNAPSHOT
+ 335361 Fixed 'jetty.sh check' to show current PID when JETTY_PID env. variable is set + 335361 Fixed 'jetty.sh check' to show current PID when JETTY_PID env. variable is set
+ 335641 Cleaned up dispatch handling to avoid key.interestOps==0 when undispatched + 335641 Cleaned up dispatch handling to avoid key.interestOps==0 when undispatched
+ 335681 Improve ChannelEndPoint.close() to avoid spinning + 335681 Improve ChannelEndPoint.close() to avoid spinning
+ 335836 Race when updating SelectChannelEndPoint._dispatched
jetty-7.2.2.v20101205 5 December 2010 jetty-7.2.2.v20101205 5 December 2010
+ JETTY-1308 327109 (re)fixed AJP handling of empty packets + JETTY-1308 327109 (re)fixed AJP handling of empty packets

View File

@ -4,11 +4,11 @@
// All rights reserved. This program and the accompanying materials // All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0 // are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution. // and Apache License v2.0 which accompanies this distribution.
// The Eclipse Public License is available at // The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html // http://www.eclipse.org/legal/epl-v10.html
// The Apache License v2.0 is available at // The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php // http://www.opensource.org/licenses/apache2.0.php
// You may elect to redistribute this code under either of these licenses. // You may elect to redistribute this code under either of these licenses.
// ======================================================================== // ========================================================================
package org.eclipse.jetty.io.nio; package org.eclipse.jetty.io.nio;
@ -43,8 +43,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
private volatile Connection _connection; private volatile Connection _connection;
private boolean _dispatched = false; private boolean _dispatched = false;
private boolean _redispatched = false; private boolean _redispatched = false;
private volatile boolean _writable = true; private volatile boolean _writable = true;
private SelectionKey _key; private SelectionKey _key;
private int _interestOps; private int _interestOps;
private boolean _readBlocked; private boolean _readBlocked;
@ -62,11 +62,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_selectSet = selectSet; _selectSet = selectSet;
_dispatched = false; _dispatched = false;
_redispatched = false; _redispatched = false;
_open=true; _open=true;
_key = key; _key = key;
_connection = _manager.newConnection(channel,this); _connection = _manager.newConnection(channel,this);
scheduleIdle(); scheduleIdle();
} }
@ -75,16 +75,16 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
throws IOException throws IOException
{ {
super(channel); super(channel);
_manager = selectSet.getManager(); _manager = selectSet.getManager();
_selectSet = selectSet; _selectSet = selectSet;
_dispatched = false; _dispatched = false;
_redispatched = false; _redispatched = false;
_open=true; _open=true;
_key = key; _key = key;
_connection = _manager.newConnection(channel,this); _connection = _manager.newConnection(channel,this);
scheduleIdle(); scheduleIdle();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -95,19 +95,19 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
return _key; return _key;
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public SelectorManager getSelectManager() public SelectorManager getSelectManager()
{ {
return _manager; return _manager;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public Connection getConnection() public Connection getConnection()
{ {
return _connection; return _connection;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void setConnection(Connection connection) public void setConnection(Connection connection)
{ {
@ -118,9 +118,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** Called by selectSet to schedule handling /** Called by selectSet to schedule handling
* *
*/ */
public void schedule() public void schedule()
{ {
synchronized (this) synchronized (this)
{ {
@ -132,7 +132,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
this.notifyAll(); this.notifyAll();
return; return;
} }
// If there are threads dispatched reading and writing // If there are threads dispatched reading and writing
if (_readBlocked || _writeBlocked) if (_readBlocked || _writeBlocked)
{ {
@ -144,7 +144,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
// wake them up is as good as a dispatched. // wake them up is as good as a dispatched.
this.notifyAll(); this.notifyAll();
// we are not interested in further selecting // we are not interested in further selecting
if (_dispatched) if (_dispatched)
_key.interestOps(0); _key.interestOps(0);
@ -179,9 +179,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
} }
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void dispatch() public void dispatch()
{ {
synchronized(this) synchronized(this)
{ {
@ -191,9 +191,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
} }
else else
{ {
_dispatched = _manager.dispatch(_handler); _dispatched = true;
if(!_dispatched) boolean dispatched = _manager.dispatch(_handler);
if(!dispatched)
{ {
_dispatched = false;
Log.warn("Dispatched Failed!"); Log.warn("Dispatched Failed!");
updateKey(); updateKey();
} }
@ -203,12 +205,12 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Called when a dispatched thread is no longer handling the endpoint. * Called when a dispatched thread is no longer handling the endpoint.
* The selection key operations are updated. * The selection key operations are updated.
* @return If false is returned, the endpoint has been redispatched and * @return If false is returned, the endpoint has been redispatched and
* thread must keep handling the endpoint. * thread must keep handling the endpoint.
*/ */
private boolean undispatch() protected boolean undispatch()
{ {
synchronized (this) synchronized (this)
{ {
@ -234,7 +236,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
_idleTimestamp=0; _idleTimestamp=0;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void checkIdleTimestamp(long now) public void checkIdleTimestamp(long now)
{ {
@ -300,7 +302,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
return !(_dispatched || getConnection().isSuspended()); return !(_dispatched || getConnection().isSuspended());
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
* Allows thread to block waiting for further events. * Allows thread to block waiting for further events.
@ -312,7 +314,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
long start=_selectSet.getNow(); long start=_selectSet.getNow();
try try
{ {
_readBlocked=true; _readBlocked=true;
while (isOpen() && _readBlocked) while (isOpen() && _readBlocked)
{ {
@ -350,7 +352,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
long start=_selectSet.getNow(); long start=_selectSet.getNow();
try try
{ {
_writeBlocked=true; _writeBlocked=true;
while (isOpen() && _writeBlocked) while (isOpen() && _writeBlocked)
{ {
@ -384,14 +386,14 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
_writable=writable; _writable=writable;
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
public void scheduleWrite() public void scheduleWrite()
{ {
_writable=false; _writable=false;
updateKey(); updateKey();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Updates selection key. Adds operations types to the selection key as needed. No operations * Updates selection key. Adds operations types to the selection key as needed. No operations
@ -405,8 +407,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
int ops=-1; int ops=-1;
if (getChannel().isOpen()) if (getChannel().isOpen())
{ {
_interestOps = _interestOps =
((!_dispatched || _readBlocked) ? SelectionKey.OP_READ : 0) ((!_dispatched || _readBlocked) ? SelectionKey.OP_READ : 0)
| ((!_writable || _writeBlocked) ? SelectionKey.OP_WRITE : 0); | ((!_writable || _writeBlocked) ? SelectionKey.OP_WRITE : 0);
try try
{ {
@ -425,7 +427,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_selectSet.addChange(this); _selectSet.addChange(this);
_selectSet.wakeup(); _selectSet.wakeup();
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/** /**
* Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey * Synchronize the interestOps with the actual key. Call is scheduled by a call to updateKey
@ -443,7 +445,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
SelectableChannel sc = (SelectableChannel)getChannel(); SelectableChannel sc = (SelectableChannel)getChannel();
if (sc.isRegistered()) if (sc.isRegistered())
{ {
updateKey(); updateKey();
} }
else else
{ {
@ -482,11 +484,11 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
_key=null; _key=null;
} }
} }
else else
{ {
if (_key!=null && _key.isValid()) if (_key!=null && _key.isValid())
_key.cancel(); _key.cancel();
cancelIdle(); cancelIdle();
if (_open) if (_open)
{ {
@ -499,9 +501,9 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
/* /*
*/ */
private void handle() protected void handle()
{ {
boolean dispatched=true; boolean dispatched=true;
try try
@ -514,7 +516,7 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
{ {
final Connection next = _connection.handle(); final Connection next = _connection.handle();
if (next!=_connection) if (next!=_connection)
{ {
_connection=next; _connection=next;
continue; continue;
} }
@ -575,20 +577,20 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
catch (IOException e) catch (IOException e)
{ {
Log.ignore(e); Log.ignore(e);
} }
finally finally
{ {
updateKey(); updateKey();
} }
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public String toString() public String toString()
{ {
synchronized(this) synchronized(this)
{ {
return "SCEP@" + hashCode() + "\t[d=" + _dispatched + ",io=" + _interestOps+ return "SCEP@" + hashCode() + " [d=" + _dispatched + ",io=" + _interestOps+
",w=" + _writable + ",rb=" + _readBlocked + ",wb=" + _writeBlocked + "]"; ",w=" + _writable + ",rb=" + _readBlocked + ",wb=" + _writeBlocked + "]";
} }
} }