Skip to content

Fix memory leaks in the Windows (WinRT) backend#454

Closed
report02 wants to merge 1 commit into
tinygo-org:devfrom
report02:fix/windows-memory-leaks
Closed

Fix memory leaks in the Windows (WinRT) backend#454
report02 wants to merge 1 commit into
tinygo-org:devfrom
report02:fix/windows-memory-leaks

Conversation

@report02
Copy link
Copy Markdown

Many WinRT/COM objects returned from Get*, GetAt, GetResults, DetachBuffer, New*, and *Async calls were never released, causing significant leaks — some on hot paths (per advertisement packet, per read/write, per notification). This change pairs each of those calls with a Release()/Close() and fixes several related bugs:

  • gap_windows.go getScanResultFromArgs: drop the duplicate GetAdvertisement() call, release vectors, elements and buffers.
  • gap_windows.go Adapter.Connect: release bleDeviceOp, dID, gattSessionOp; release bleDevice/newSession on error paths.
  • gap_windows.go Device.Disconnect: use a pointer receiver + sync.Once on the underlying struct to guard against double-release.
  • gap_windows.go Advertisement.Configure: release vec, manData, buf, and release each writer per iteration instead of via defer.
  • gattc_windows.go DiscoverServices / DiscoverCharacteristics: release op, result, vector; close unmatched services/characteristics; fix loop-variable capture in the srv.Close() goroutine.
  • gattc_windows.go DeviceCharacteristic.Read: release readOp, result, buffer, datareader.
  • gattc_windows.go write/EnableNotificationsWithMode: release asyncOp and writeOp.
  • gatts_windows.go AddService: release op/result/localService/params/ createCharOp/characteristicResults and unkept characteristics; keep serviceProvider, handler tokens and handlers tracked in a package map keyed by UUID so RemoveService can stop & release them.
  • gatts_windows.go RemoveService: stop the previously-started provider, remove handler registrations, and release everything (instead of creating a brand-new provider).
  • gatts_windows.go write/read requested handlers: release reqAsyncOp, gattWriteRequest/gattReadRequest, and the GetValue buffer.
  • bufferToSlice now releases its IBuffer argument.

Many WinRT/COM objects returned from Get*, GetAt, GetResults,
DetachBuffer, New*, and *Async calls were never released, causing
significant leaks — some on hot paths (per advertisement packet,
per read/write, per notification). This change pairs each of those
calls with a Release()/Close() and fixes several related bugs:

- gap_windows.go getScanResultFromArgs: drop the duplicate
  GetAdvertisement() call, release vectors, elements and buffers.
- gap_windows.go Adapter.Connect: release bleDeviceOp, dID,
  gattSessionOp; release bleDevice/newSession on error paths.
- gap_windows.go Device.Disconnect: use a pointer receiver + sync.Once
  on the underlying struct to guard against double-release.
- gap_windows.go Advertisement.Configure: release vec, manData, buf,
  and release each writer per iteration instead of via defer.
- gattc_windows.go DiscoverServices / DiscoverCharacteristics: release
  op, result, vector; close unmatched services/characteristics; fix
  loop-variable capture in the srv.Close() goroutine.
- gattc_windows.go DeviceCharacteristic.Read: release readOp, result,
  buffer, datareader.
- gattc_windows.go write/EnableNotificationsWithMode: release asyncOp
  and writeOp.
- gatts_windows.go AddService: release op/result/localService/params/
  createCharOp/characteristicResults and unkept characteristics; keep
  serviceProvider, handler tokens and handlers tracked in a package
  map keyed by UUID so RemoveService can stop & release them.
- gatts_windows.go RemoveService: stop the previously-started provider,
  remove handler registrations, and release everything (instead of
  creating a brand-new provider).
- gatts_windows.go write/read requested handlers: release reqAsyncOp,
  gattWriteRequest/gattReadRequest, and the GetValue buffer.
- bufferToSlice now releases its IBuffer argument.
@acouvreur
Copy link
Copy Markdown
Member

Hello @report02

What about the changes made in #453 ?

Can we try to see if some are missing in the original PR ? I believe most of the changes were already caught, if not, can you target the branch windows-memory-leaks so that we can see the difference ?

@report02 report02 closed this May 21, 2026
@report02 report02 deleted the fix/windows-memory-leaks branch May 21, 2026 22:05
@report02
Copy link
Copy Markdown
Author

Yes. Sorry I posted it too soon.

@acouvreur
Copy link
Copy Markdown
Member

Yes. Sorry I posted it too soon.

No problem! Thank you for contributing! Let me know if you need some help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants