@@ -220,8 +220,10 @@ public void testReferenceCount() {
220220 assertEquals (0 , buf2 .refCnt ());
221221 assertEquals (0 , dup2 .refCnt ());
222222 assertEquals (0 , alloc .getFreeBufferCount ());
223- assertException (dup2 ::position );
224- assertException (buf2 ::position );
223+ // these should not throw an exception because they are heap buffers.
224+ // off-heap buffers would throw an exception if trying to call a method once released.
225+ dup2 .position ();
226+ buf2 .position ();
225227
226228 // duplicate the buf1, if the dup1 released, buf1 will also be released (MultipleByteBuffer)
227229 ByteBuff dup1 = buf1 .duplicate ();
@@ -414,4 +416,103 @@ public void testHeapAllocationRatio() {
414416 alloc1 .allocate (1024 );
415417 Assert .assertEquals (getHeapAllocationRatio (HEAP , HEAP , alloc1 ), 1024f / (1024f + 2048f ), 1e-6 );
416418 }
419+
420+ /**
421+ * Tests that we only call the logic in checkRefCount for ByteBuff's that have a non-NONE
422+ * recycler.
423+ */
424+ @ Test
425+ public void testCheckRefCountOnlyWithRecycler () {
426+ TrackingSingleByteBuff singleBuff = new TrackingSingleByteBuff (ByteBuffer .allocate (1 ));
427+ singleBuff .get ();
428+ assertEquals (1 , singleBuff .getCheckRefCountCalls ());
429+ assertEquals (0 , singleBuff .getRefCntCalls ());
430+ singleBuff = new TrackingSingleByteBuff (() -> {
431+ // do nothing, just so we dont use NONE recycler
432+ }, ByteBuffer .allocate (1 ));
433+ singleBuff .get ();
434+ assertEquals (1 , singleBuff .getCheckRefCountCalls ());
435+ assertEquals (1 , singleBuff .getRefCntCalls ());
436+
437+ TrackingMultiByteBuff multiBuff = new TrackingMultiByteBuff (ByteBuffer .allocate (1 ));
438+
439+ multiBuff .get ();
440+ assertEquals (1 , multiBuff .getCheckRefCountCalls ());
441+ assertEquals (0 , multiBuff .getRefCntCalls ());
442+ multiBuff = new TrackingMultiByteBuff (() -> {
443+ // do nothing, just so we dont use NONE recycler
444+ }, ByteBuffer .allocate (1 ));
445+ multiBuff .get ();
446+ assertEquals (1 , multiBuff .getCheckRefCountCalls ());
447+ assertEquals (1 , multiBuff .getRefCntCalls ());
448+ }
449+
450+ private static class TrackingSingleByteBuff extends SingleByteBuff {
451+
452+ int refCntCalls = 0 ;
453+ int checkRefCountCalls = 0 ;
454+
455+ public TrackingSingleByteBuff (ByteBuffer buf ) {
456+ super (buf );
457+ }
458+
459+ public TrackingSingleByteBuff (ByteBuffAllocator .Recycler recycler , ByteBuffer buf ) {
460+ super (recycler , buf );
461+ }
462+
463+ public int getRefCntCalls () {
464+ return refCntCalls ;
465+ }
466+
467+ public int getCheckRefCountCalls () {
468+ return checkRefCountCalls ;
469+ }
470+
471+ @ Override
472+ protected void checkRefCount () {
473+ checkRefCountCalls ++;
474+ super .checkRefCount ();
475+ }
476+
477+ @ Override
478+ public int refCnt () {
479+ refCntCalls ++;
480+ return super .refCnt ();
481+ }
482+ }
483+
484+ private static class TrackingMultiByteBuff extends MultiByteBuff {
485+
486+ int refCntCalls = 0 ;
487+ int checkRefCountCalls = 0 ;
488+
489+ public TrackingMultiByteBuff (ByteBuffer ... items ) {
490+ super (items );
491+ }
492+
493+ public TrackingMultiByteBuff (ByteBuffAllocator .Recycler recycler , ByteBuffer ... items ) {
494+ super (recycler , items );
495+ }
496+
497+ public int getRefCntCalls () {
498+ return refCntCalls ;
499+ }
500+
501+ public int getCheckRefCountCalls () {
502+ return checkRefCountCalls ;
503+ }
504+
505+ @ Override
506+ protected void checkRefCount () {
507+ checkRefCountCalls ++;
508+ super .checkRefCount ();
509+ }
510+
511+ @ Override
512+ public int refCnt () {
513+ refCntCalls ++;
514+ return super .refCnt ();
515+ }
516+ }
517+
417518}
0 commit comments