Author Topic: Which is the proper way to remove a callback with WASAPI?  (Read 205 times)

Dev01

  • Posts: 25
Which is the proper way to remove a callback with WASAPI?
It seems that there is a handle leak.

I mean: 
Code: [Select]
                mWASAPIOutProc = new WASAPIPROC(WASAPIOutCallback);
                //Handles: 527
                mOutputs[index].Initialized = BassWasapi.BASS_WASAPI_Init(index, 0, 0, BASSWASAPIInit.BASS_WASAPI_EVENT, 0.1f, 0, mWASAPIOutProc, (IntPtr)index);               
                ret = BassWasapi.BASS_WASAPI_Stop(true);
                ret = BassWasapi.BASS_WASAPI_Free();
                //Handles: 528

leaks 1 handle

instead
Code: [Select]
                mWASAPIOutProc = new WASAPIPROC(WASAPIOutCallback);
                //Handles: 532
                mOutputs[index].Initialized = BassWasapi.BASS_WASAPI_Init(index, 0, 0, BASSWASAPIInit.BASS_WASAPI_EVENT, 0.1f, 0, null, (IntPtr)index);               
                ret = BassWasapi.BASS_WASAPI_Stop(true);
                ret = BassWasapi.BASS_WASAPI_Free();
                //Handles: 532

No handle leak.

I've tried to put
Code: [Select]
return 0;

in the callback but non succeed.

Thanks.

Ian @ un4seen

  • Administrator
  • Posts: 20437
I'm not a .Net user myself, but perhaps setting the "mWASAPIOutProc" variable to null (after calling BASS_WASAPI_Free) will allow .Net to garbage collect the delegate? Note garbage collection probably won't happen immediately unless you call GC.Collect.

radio42

  • Posts: 4576
Yes, exactly how Ian explained it.
Make sure the callback delegate isn't used anymore (by calling BASS_WASAPI_Free) and then simply set it to null.

Dev01

  • Posts: 25
It doesn't seem to work.
Code: [Select]
                //Handles: 550
                WASAPIPROC wASAPIOutProc = new WASAPIPROC(WASAPIOutCallback);               
                mOutputs[2].Initialized = BassWasapi.BASS_WASAPI_Init(2, 0, 0, BASSWASAPIInit.BASS_WASAPI_EVENT, 0.1f, 0, wASAPIOutProc, (IntPtr)2);

                ret = BassWasapi.BASS_WASAPI_SetDevice(2);               
                ret = BassWasapi.BASS_WASAPI_Stop(true);
                ret = BassWasapi.BASS_WASAPI_Free();
                wASAPIOutProc = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
                //Handles: 551

Instead, passing null to BASS_WASAPI_Init() doesn't make the handles raise.
Other ideas?
Can you confirm that in C there's no leak?
« Last Edit: 2 Nov '17 - 17:06 by Dev01 »

Ian @ un4seen

  • Administrator
  • Posts: 20437
To confirm whether there is a leak, does the handle count go up by 1 again if you call that code again?

Dev01

  • Posts: 25
Yes.

09:01:43.502 Before. MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 526, GDIObjects: 36, GetUSERObject: 107, Threads: 20
09:01:43.512 After.    MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 527, GDIObjects: 36, GetUSERObject: 107, Threads: 20

09:02:01.670 Before. MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 527, GDIObjects: 36, GetUSERObject: 107, Threads: 20
09:02:01.681 After.    MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 528, GDIObjects: 36, GetUSERObject: 107, Threads: 20

09:02:13.222 Before. MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 528, GDIObjects: 36, GetUSERObject: 107, Threads: 20
09:02:13.232 After.    MemoryWorking64: 54 MB, MemoryPeakWorking64 54 MB, Handles 529, GDIObjects: 36, GetUSERObject: 107, Threads: 20

Ian @ un4seen

  • Administrator
  • Posts: 20437
Oh yes, I see what it is now. The BASSWASAPI buffering threads are calling AvSetMmThreadCharacteristics without subsequently calling AvRevertMmThreadCharacteristics. Here's an update to fix that:

   www.un4seen.com/stuff/basswasapi.zip

Let me know if you still see a problem with that.

Dev01

  • Posts: 25
Thank you Ian, the handle leak seems solved.
« Last Edit: 6 Nov '17 - 09:07 by Dev01 »

Ian @ un4seen

  • Administrator
  • Posts: 20437
Good to hear that the problem is fixed now. The BASSWASAPI update will be released shortly. You can continue to use the update posted above (it is a "release" build).