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