Skip to content

Commit 0f67736

Browse files
committed
JAVA-660: Took call to OutMessage.doneWithMessage out of the recursively-called method, to avoid having it called more than once. Protected OutMessage by setting the buffer to null and checking for null everywhere it's used.
1 parent f71837e commit 0f67736

File tree

2 files changed

+74
-49
lines changed

2 files changed

+74
-49
lines changed

src/main/com/mongodb/DBTCPConnector.java

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -252,64 +252,67 @@ public Response call( DB db , DBCollection coll , OutMessage m , ServerAddress h
252252
*/
253253
@Override
254254
public Response call( DB db, DBCollection coll, OutMessage m, ServerAddress hostNeeded, int retries, ReadPreference readPref, DBDecoder decoder ){
255-
256255
try {
257-
if (readPref == null)
258-
readPref = ReadPreference.primary();
256+
return innerCall(db, coll, m, hostNeeded, retries, readPref, decoder);
257+
} finally {
258+
m.doneWithMessage();
259+
}
260+
}
259261

260-
if (readPref == ReadPreference.primary() && m.hasOption( Bytes.QUERYOPTION_SLAVEOK ))
261-
readPref = ReadPreference.secondaryPreferred();
262+
private Response innerCall(final DB db, final DBCollection coll, final OutMessage m, final ServerAddress hostNeeded, final int retries, ReadPreference readPref, final DBDecoder decoder) {
263+
if (readPref == null)
264+
readPref = ReadPreference.primary();
262265

263-
boolean secondaryOk = !(readPref == ReadPreference.primary());
266+
if (readPref == ReadPreference.primary() && m.hasOption( Bytes.QUERYOPTION_SLAVEOK ))
267+
readPref = ReadPreference.secondaryPreferred();
264268

265-
_checkClosed();
266-
if (!secondaryOk)
267-
checkMaster( false, !secondaryOk );
269+
boolean secondaryOk = !(readPref == ReadPreference.primary());
268270

269-
final MyPort mp = _myPort.get();
270-
final DBPort port = mp.get( false , readPref, hostNeeded );
271+
_checkClosed();
272+
if (!secondaryOk)
273+
checkMaster( false, !secondaryOk );
271274

272-
Response res = null;
273-
boolean retry = false;
274-
try {
275-
port.checkAuth( db );
276-
res = port.call( m , coll, decoder );
277-
if ( res._responseTo != m.getId() )
278-
throw new MongoException( "ids don't match" );
279-
}
280-
catch ( IOException ioe ){
281-
mp.error( port , ioe );
282-
retry = retries > 0 && !coll._name.equals( "$cmd" )
283-
&& !(ioe instanceof SocketTimeoutException) && _error( ioe, secondaryOk );
284-
if ( !retry ){
285-
throw new MongoException.Network( "can't call something : " + port.host() + "/" + db,
286-
ioe );
287-
}
288-
}
289-
catch ( RuntimeException re ){
290-
mp.error( port , re );
291-
throw re;
292-
} finally {
293-
mp.done( port );
275+
final MyPort mp = _myPort.get();
276+
final DBPort port = mp.get( false , readPref, hostNeeded );
277+
278+
Response res = null;
279+
boolean retry = false;
280+
try {
281+
port.checkAuth( db );
282+
res = port.call( m , coll, decoder );
283+
if ( res._responseTo != m.getId() )
284+
throw new MongoException( "ids don't match" );
285+
}
286+
catch ( IOException ioe ){
287+
mp.error( port , ioe );
288+
retry = retries > 0 && !coll._name.equals( "$cmd" )
289+
&& !(ioe instanceof SocketTimeoutException) && _error( ioe, secondaryOk );
290+
if ( !retry ){
291+
throw new MongoException.Network( "can't call something : " + port.host() + "/" + db,
292+
ioe );
294293
}
294+
}
295+
catch ( RuntimeException re ){
296+
mp.error( port , re );
297+
throw re;
298+
} finally {
299+
mp.done( port );
300+
}
295301

296-
if (retry)
297-
return call( db , coll , m , hostNeeded , retries - 1 , readPref, decoder );
302+
if (retry)
303+
return innerCall( db , coll , m , hostNeeded , retries - 1 , readPref, decoder );
298304

299-
ServerError err = res.getError();
305+
ServerError err = res.getError();
300306

301-
if ( err != null && err.isNotMasterError() ){
302-
checkMaster( true , true );
303-
if ( retries <= 0 ){
304-
throw new MongoException( "not talking to master and retries used up" );
305-
}
306-
return call( db , coll , m , hostNeeded , retries -1, readPref, decoder );
307+
if ( err != null && err.isNotMasterError() ){
308+
checkMaster( true , true );
309+
if ( retries <= 0 ){
310+
throw new MongoException( "not talking to master and retries used up" );
307311
}
308-
309-
return res;
310-
} finally {
311-
m.doneWithMessage();
312+
return innerCall( db , coll , m , hostNeeded , retries -1, readPref, decoder );
312313
}
314+
315+
return res;
313316
}
314317

315318
public ServerAddress getAddress(){

src/main/com/mongodb/OutMessage.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,20 +221,38 @@ private void writeMessagePrologue(final OpCode opCode) {
221221
}
222222

223223
void prepare(){
224+
if (_buffer == null) {
225+
throw new IllegalStateException("Already closed");
226+
}
227+
224228
_buffer.writeInt( 0 , _buffer.size() );
225229
}
226230

227231
void pipe( OutputStream out ) throws IOException {
232+
if (_buffer == null) {
233+
throw new IllegalStateException("Already closed");
234+
}
235+
228236
_buffer.pipe( out );
229237
}
230238

231-
int size(){
239+
int size() {
240+
if (_buffer == null) {
241+
throw new IllegalStateException("Already closed");
242+
}
243+
232244
return _buffer.size();
233245
}
234246

235-
void doneWithMessage(){
247+
void doneWithMessage() {
248+
if (_buffer == null) {
249+
throw new IllegalStateException("Only call this once per instance");
250+
}
251+
236252
_buffer.reset();
237253
_mongo._bufferPool.done(_buffer);
254+
_buffer = null;
255+
done();
238256
}
239257

240258
boolean hasOption( int option ){
@@ -263,6 +281,10 @@ int getNumDocuments() {
263281

264282
@Override
265283
public int putObject(BSONObject o) {
284+
if (_buffer == null) {
285+
throw new IllegalStateException("Already closed");
286+
}
287+
266288
// check max size
267289
int objectSize = _encoder.writeObject(_buf, o);
268290
if (objectSize > Math.max(_mongo.getConnector().getMaxBsonObjectSize(), Bytes.MAX_OBJECT_SIZE)) {
@@ -274,7 +296,7 @@ public int putObject(BSONObject o) {
274296

275297
private final Mongo _mongo;
276298
private final DBCollection _collection;
277-
private final PoolOutputBuffer _buffer;
299+
private PoolOutputBuffer _buffer;
278300
private final int _id;
279301
private final OpCode _opCode;
280302
private final int _queryOptions;

0 commit comments

Comments
 (0)