first commit
This commit is contained in:
208
windows/foundation/asyncoperationcompletedhandler.go
Normal file
208
windows/foundation/asyncoperationcompletedhandler.go
Normal file
@ -0,0 +1,208 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/saltosystems/winrt-go/internal/delegate"
|
||||
"github.com/saltosystems/winrt-go/internal/kernel32"
|
||||
)
|
||||
|
||||
const GUIDAsyncOperationCompletedHandler string = "fcdcf02c-e5d8-4478-915a-4d90b74b83a5"
|
||||
const SignatureAsyncOperationCompletedHandler string = "delegate({fcdcf02c-e5d8-4478-915a-4d90b74b83a5})"
|
||||
|
||||
type AsyncOperationCompletedHandler struct {
|
||||
ole.IUnknown
|
||||
sync.Mutex
|
||||
refs uintptr
|
||||
IID ole.GUID
|
||||
}
|
||||
|
||||
type AsyncOperationCompletedHandlerVtbl struct {
|
||||
ole.IUnknownVtbl
|
||||
Invoke uintptr
|
||||
}
|
||||
|
||||
type AsyncOperationCompletedHandlerCallback func(instance *AsyncOperationCompletedHandler, asyncInfo *IAsyncOperation, asyncStatus AsyncStatus)
|
||||
|
||||
var callbacksAsyncOperationCompletedHandler = &asyncOperationCompletedHandlerCallbacks{
|
||||
mu: &sync.Mutex{},
|
||||
callbacks: make(map[unsafe.Pointer]AsyncOperationCompletedHandlerCallback),
|
||||
}
|
||||
|
||||
var releaseChannelsAsyncOperationCompletedHandler = &asyncOperationCompletedHandlerReleaseChannels{
|
||||
mu: &sync.Mutex{},
|
||||
chans: make(map[unsafe.Pointer]chan struct{}),
|
||||
}
|
||||
|
||||
func NewAsyncOperationCompletedHandler(iid *ole.GUID, callback AsyncOperationCompletedHandlerCallback) *AsyncOperationCompletedHandler {
|
||||
// create type instance
|
||||
size := unsafe.Sizeof(*(*AsyncOperationCompletedHandler)(nil))
|
||||
instPtr := kernel32.Malloc(size)
|
||||
inst := (*AsyncOperationCompletedHandler)(instPtr)
|
||||
|
||||
// get the callbacks for the VTable
|
||||
callbacks := delegate.RegisterCallbacks(instPtr, inst)
|
||||
|
||||
// the VTable should also be allocated in the heap
|
||||
sizeVTable := unsafe.Sizeof(*(*AsyncOperationCompletedHandlerVtbl)(nil))
|
||||
vTablePtr := kernel32.Malloc(sizeVTable)
|
||||
|
||||
inst.RawVTable = (*interface{})(vTablePtr)
|
||||
|
||||
vTable := (*AsyncOperationCompletedHandlerVtbl)(vTablePtr)
|
||||
vTable.IUnknownVtbl = ole.IUnknownVtbl{
|
||||
QueryInterface: callbacks.QueryInterface,
|
||||
AddRef: callbacks.AddRef,
|
||||
Release: callbacks.Release,
|
||||
}
|
||||
vTable.Invoke = callbacks.Invoke
|
||||
|
||||
// Initialize all properties: the malloc may contain garbage
|
||||
inst.IID = *iid // copy contents
|
||||
inst.Mutex = sync.Mutex{}
|
||||
inst.refs = 0
|
||||
|
||||
callbacksAsyncOperationCompletedHandler.add(unsafe.Pointer(inst), callback)
|
||||
|
||||
// See the docs in the releaseChannelsAsyncOperationCompletedHandler struct
|
||||
releaseChannelsAsyncOperationCompletedHandler.acquire(unsafe.Pointer(inst))
|
||||
|
||||
inst.addRef()
|
||||
return inst
|
||||
}
|
||||
|
||||
func (r *AsyncOperationCompletedHandler) GetIID() *ole.GUID {
|
||||
return &r.IID
|
||||
}
|
||||
|
||||
// addRef increments the reference counter by one
|
||||
func (r *AsyncOperationCompletedHandler) addRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.refs++
|
||||
return r.refs
|
||||
}
|
||||
|
||||
// removeRef decrements the reference counter by one. If it was already zero, it will just return zero.
|
||||
func (r *AsyncOperationCompletedHandler) removeRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
if r.refs > 0 {
|
||||
r.refs--
|
||||
}
|
||||
|
||||
return r.refs
|
||||
}
|
||||
|
||||
func (instance *AsyncOperationCompletedHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr {
|
||||
asyncInfoPtr := rawArgs0
|
||||
asyncStatusRaw := (int32)(uintptr(rawArgs1))
|
||||
|
||||
// See the quote above.
|
||||
asyncInfo := (*IAsyncOperation)(asyncInfoPtr)
|
||||
asyncStatus := (AsyncStatus)(asyncStatusRaw)
|
||||
if callback, ok := callbacksAsyncOperationCompletedHandler.get(instancePtr); ok {
|
||||
callback(instance, asyncInfo, asyncStatus)
|
||||
}
|
||||
return ole.S_OK
|
||||
}
|
||||
|
||||
func (instance *AsyncOperationCompletedHandler) AddRef() uintptr {
|
||||
return instance.addRef()
|
||||
}
|
||||
|
||||
func (instance *AsyncOperationCompletedHandler) Release() uintptr {
|
||||
rem := instance.removeRef()
|
||||
if rem == 0 {
|
||||
// We're done.
|
||||
instancePtr := unsafe.Pointer(instance)
|
||||
callbacksAsyncOperationCompletedHandler.delete(instancePtr)
|
||||
|
||||
// stop release channels used to avoid
|
||||
// https://github.com/golang/go/issues/55015
|
||||
releaseChannelsAsyncOperationCompletedHandler.release(instancePtr)
|
||||
|
||||
kernel32.Free(unsafe.Pointer(instance.RawVTable))
|
||||
kernel32.Free(instancePtr)
|
||||
}
|
||||
return rem
|
||||
}
|
||||
|
||||
type asyncOperationCompletedHandlerCallbacks struct {
|
||||
mu *sync.Mutex
|
||||
callbacks map[unsafe.Pointer]AsyncOperationCompletedHandlerCallback
|
||||
}
|
||||
|
||||
func (m *asyncOperationCompletedHandlerCallbacks) add(p unsafe.Pointer, v AsyncOperationCompletedHandlerCallback) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.callbacks[p] = v
|
||||
}
|
||||
|
||||
func (m *asyncOperationCompletedHandlerCallbacks) get(p unsafe.Pointer) (AsyncOperationCompletedHandlerCallback, bool) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
v, ok := m.callbacks[p]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (m *asyncOperationCompletedHandlerCallbacks) delete(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
delete(m.callbacks, p)
|
||||
}
|
||||
|
||||
// typedEventHandlerReleaseChannels keeps a map with channels
|
||||
// used to keep a goroutine alive during the lifecycle of this object.
|
||||
// This is required to avoid causing a deadlock error.
|
||||
// See this: https://github.com/golang/go/issues/55015
|
||||
type asyncOperationCompletedHandlerReleaseChannels struct {
|
||||
mu *sync.Mutex
|
||||
chans map[unsafe.Pointer]chan struct{}
|
||||
}
|
||||
|
||||
func (m *asyncOperationCompletedHandlerReleaseChannels) acquire(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
c := make(chan struct{})
|
||||
m.chans[p] = c
|
||||
|
||||
go func() {
|
||||
// we need a timer to trick the go runtime into
|
||||
// thinking there's still something going on here
|
||||
// but we are only really interested in <-c
|
||||
t := time.NewTimer(time.Minute)
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
t.Reset(time.Minute)
|
||||
case <-c:
|
||||
t.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (m *asyncOperationCompletedHandlerReleaseChannels) release(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if c, ok := m.chans[p]; ok {
|
||||
close(c)
|
||||
delete(m.chans, p)
|
||||
}
|
||||
}
|
17
windows/foundation/asyncstatus.go
Normal file
17
windows/foundation/asyncstatus.go
Normal file
@ -0,0 +1,17 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
type AsyncStatus int32
|
||||
|
||||
const SignatureAsyncStatus string = "enum(Windows.Foundation.AsyncStatus;i4)"
|
||||
|
||||
const (
|
||||
AsyncStatusCanceled AsyncStatus = 2
|
||||
AsyncStatusCompleted AsyncStatus = 1
|
||||
AsyncStatusError AsyncStatus = 3
|
||||
AsyncStatusStarted AsyncStatus = 0
|
||||
)
|
223
windows/foundation/collections/ivector.go
Normal file
223
windows/foundation/collections/ivector.go
Normal file
@ -0,0 +1,223 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package collections
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const GUIDIVector string = "913337e9-11a1-4345-a3a2-4e7f956e222d"
|
||||
const SignatureIVector string = "{913337e9-11a1-4345-a3a2-4e7f956e222d}"
|
||||
|
||||
type IVector struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type IVectorVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
GetAt uintptr
|
||||
GetSize uintptr
|
||||
GetView uintptr
|
||||
IndexOf uintptr
|
||||
SetAt uintptr
|
||||
InsertAt uintptr
|
||||
RemoveAt uintptr
|
||||
Append uintptr
|
||||
RemoveAtEnd uintptr
|
||||
Clear uintptr
|
||||
GetMany uintptr
|
||||
ReplaceAll uintptr
|
||||
}
|
||||
|
||||
func (v *IVector) VTable() *IVectorVtbl {
|
||||
return (*IVectorVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *IVector) GetAt(index uint32) (unsafe.Pointer, error) {
|
||||
var out unsafe.Pointer
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetAt,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(index), // in uint32
|
||||
uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IVector) GetSize() (uint32, error) {
|
||||
var out uint32
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetSize,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out uint32
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return 0, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IVector) GetView() (*IVectorView, error) {
|
||||
var out *IVectorView
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetView,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out IVectorView
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IVector) IndexOf(value unsafe.Pointer) (uint32, bool, error) {
|
||||
var index uint32
|
||||
var out bool
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().IndexOf,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(value), // in unsafe.Pointer
|
||||
uintptr(unsafe.Pointer(&index)), // out uint32
|
||||
uintptr(unsafe.Pointer(&out)), // out bool
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return 0, false, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return index, out, nil
|
||||
}
|
||||
|
||||
func (v *IVector) SetAt(index uint32, value unsafe.Pointer) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().SetAt,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(index), // in uint32
|
||||
uintptr(value), // in unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) InsertAt(index uint32, value unsafe.Pointer) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().InsertAt,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(index), // in uint32
|
||||
uintptr(value), // in unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) RemoveAt(index uint32) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().RemoveAt,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(index), // in uint32
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) Append(value unsafe.Pointer) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().Append,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(value), // in unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) RemoveAtEnd() error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().RemoveAtEnd,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) Clear() error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().Clear,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IVector) GetMany(startIndex uint32, itemsSize uint32) ([]unsafe.Pointer, uint32, error) {
|
||||
var items []unsafe.Pointer = make([]unsafe.Pointer, itemsSize)
|
||||
var out uint32
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetMany,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(startIndex), // in uint32
|
||||
uintptr(itemsSize), // in uint32
|
||||
uintptr(unsafe.Pointer(&items[0])), // out unsafe.Pointer
|
||||
uintptr(unsafe.Pointer(&out)), // out uint32
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, 0, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return items, out, nil
|
||||
}
|
||||
|
||||
func (v *IVector) ReplaceAll(itemsSize uint32, items []unsafe.Pointer) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().ReplaceAll,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(itemsSize), // in uint32
|
||||
uintptr(unsafe.Pointer(&items[0])), // in unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
101
windows/foundation/collections/ivectorview.go
Normal file
101
windows/foundation/collections/ivectorview.go
Normal file
@ -0,0 +1,101 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package collections
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const GUIDIVectorView string = "bbe1fa4c-b0e3-4583-baef-1f1b2e483e56"
|
||||
const SignatureIVectorView string = "{bbe1fa4c-b0e3-4583-baef-1f1b2e483e56}"
|
||||
|
||||
type IVectorView struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type IVectorViewVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
GetAt uintptr
|
||||
GetSize uintptr
|
||||
IndexOf uintptr
|
||||
GetMany uintptr
|
||||
}
|
||||
|
||||
func (v *IVectorView) VTable() *IVectorViewVtbl {
|
||||
return (*IVectorViewVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *IVectorView) GetAt(index uint32) (unsafe.Pointer, error) {
|
||||
var out unsafe.Pointer
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetAt,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(index), // in uint32
|
||||
uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IVectorView) GetSize() (uint32, error) {
|
||||
var out uint32
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetSize,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out uint32
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return 0, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IVectorView) IndexOf(value unsafe.Pointer) (uint32, bool, error) {
|
||||
var index uint32
|
||||
var out bool
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().IndexOf,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(value), // in unsafe.Pointer
|
||||
uintptr(unsafe.Pointer(&index)), // out uint32
|
||||
uintptr(unsafe.Pointer(&out)), // out bool
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return 0, false, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return index, out, nil
|
||||
}
|
||||
|
||||
func (v *IVectorView) GetMany(startIndex uint32, itemsSize uint32) ([]unsafe.Pointer, uint32, error) {
|
||||
var items []unsafe.Pointer = make([]unsafe.Pointer, itemsSize)
|
||||
var out uint32
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetMany,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(startIndex), // in uint32
|
||||
uintptr(itemsSize), // in uint32
|
||||
uintptr(unsafe.Pointer(&items[0])), // out unsafe.Pointer
|
||||
uintptr(unsafe.Pointer(&out)), // out uint32
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, 0, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return items, out, nil
|
||||
}
|
12
windows/foundation/datetime.go
Normal file
12
windows/foundation/datetime.go
Normal file
@ -0,0 +1,12 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
const SignatureDateTime string = "struct(Windows.Foundation.DateTime;i8)"
|
||||
|
||||
type DateTime struct {
|
||||
UniversalTime int64
|
||||
}
|
102
windows/foundation/deferral.go
Normal file
102
windows/foundation/deferral.go
Normal file
@ -0,0 +1,102 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const SignatureDeferral string = "rc(Windows.Foundation.Deferral;{d6269732-3b7f-46a7-b40b-4fdca2a2c693})"
|
||||
|
||||
type Deferral struct {
|
||||
ole.IUnknown
|
||||
}
|
||||
|
||||
func (impl *Deferral) Complete() error {
|
||||
itf := impl.MustQueryInterface(ole.NewGUID(GUIDiDeferral))
|
||||
defer itf.Release()
|
||||
v := (*iDeferral)(unsafe.Pointer(itf))
|
||||
return v.Complete()
|
||||
}
|
||||
|
||||
func (impl *Deferral) Close() error {
|
||||
itf := impl.MustQueryInterface(ole.NewGUID(GUIDIClosable))
|
||||
defer itf.Release()
|
||||
v := (*IClosable)(unsafe.Pointer(itf))
|
||||
return v.Close()
|
||||
}
|
||||
|
||||
const GUIDiDeferral string = "d6269732-3b7f-46a7-b40b-4fdca2a2c693"
|
||||
const SignatureiDeferral string = "{d6269732-3b7f-46a7-b40b-4fdca2a2c693}"
|
||||
|
||||
type iDeferral struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type iDeferralVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
Complete uintptr
|
||||
}
|
||||
|
||||
func (v *iDeferral) VTable() *iDeferralVtbl {
|
||||
return (*iDeferralVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *iDeferral) Complete() error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().Complete,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const GUIDiDeferralFactory string = "65a1ecc5-3fb5-4832-8ca9-f061b281d13a"
|
||||
const SignatureiDeferralFactory string = "{65a1ecc5-3fb5-4832-8ca9-f061b281d13a}"
|
||||
|
||||
type iDeferralFactory struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type iDeferralFactoryVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
DeferralCreate uintptr
|
||||
}
|
||||
|
||||
func (v *iDeferralFactory) VTable() *iDeferralFactoryVtbl {
|
||||
return (*iDeferralFactoryVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func DeferralCreate(handler *DeferralCompletedHandler) (*Deferral, error) {
|
||||
inspectable, err := ole.RoGetActivationFactory("Windows.Foundation.Deferral", ole.NewGUID(GUIDiDeferralFactory))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
v := (*iDeferralFactory)(unsafe.Pointer(inspectable))
|
||||
|
||||
var out *Deferral
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().DeferralCreate,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(handler)), // in DeferralCompletedHandler
|
||||
uintptr(unsafe.Pointer(&out)), // out Deferral
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
204
windows/foundation/deferralcompletedhandler.go
Normal file
204
windows/foundation/deferralcompletedhandler.go
Normal file
@ -0,0 +1,204 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/saltosystems/winrt-go/internal/delegate"
|
||||
"github.com/saltosystems/winrt-go/internal/kernel32"
|
||||
)
|
||||
|
||||
const GUIDDeferralCompletedHandler string = "ed32a372-f3c8-4faa-9cfb-470148da3888"
|
||||
const SignatureDeferralCompletedHandler string = "delegate({ed32a372-f3c8-4faa-9cfb-470148da3888})"
|
||||
|
||||
type DeferralCompletedHandler struct {
|
||||
ole.IUnknown
|
||||
sync.Mutex
|
||||
refs uintptr
|
||||
IID ole.GUID
|
||||
}
|
||||
|
||||
type DeferralCompletedHandlerVtbl struct {
|
||||
ole.IUnknownVtbl
|
||||
Invoke uintptr
|
||||
}
|
||||
|
||||
type DeferralCompletedHandlerCallback func(instance *DeferralCompletedHandler)
|
||||
|
||||
var callbacksDeferralCompletedHandler = &deferralCompletedHandlerCallbacks{
|
||||
mu: &sync.Mutex{},
|
||||
callbacks: make(map[unsafe.Pointer]DeferralCompletedHandlerCallback),
|
||||
}
|
||||
|
||||
var releaseChannelsDeferralCompletedHandler = &deferralCompletedHandlerReleaseChannels{
|
||||
mu: &sync.Mutex{},
|
||||
chans: make(map[unsafe.Pointer]chan struct{}),
|
||||
}
|
||||
|
||||
func NewDeferralCompletedHandler(iid *ole.GUID, callback DeferralCompletedHandlerCallback) *DeferralCompletedHandler {
|
||||
// create type instance
|
||||
size := unsafe.Sizeof(*(*DeferralCompletedHandler)(nil))
|
||||
instPtr := kernel32.Malloc(size)
|
||||
inst := (*DeferralCompletedHandler)(instPtr)
|
||||
|
||||
// get the callbacks for the VTable
|
||||
callbacks := delegate.RegisterCallbacks(instPtr, inst)
|
||||
|
||||
// the VTable should also be allocated in the heap
|
||||
sizeVTable := unsafe.Sizeof(*(*DeferralCompletedHandlerVtbl)(nil))
|
||||
vTablePtr := kernel32.Malloc(sizeVTable)
|
||||
|
||||
inst.RawVTable = (*interface{})(vTablePtr)
|
||||
|
||||
vTable := (*DeferralCompletedHandlerVtbl)(vTablePtr)
|
||||
vTable.IUnknownVtbl = ole.IUnknownVtbl{
|
||||
QueryInterface: callbacks.QueryInterface,
|
||||
AddRef: callbacks.AddRef,
|
||||
Release: callbacks.Release,
|
||||
}
|
||||
vTable.Invoke = callbacks.Invoke
|
||||
|
||||
// Initialize all properties: the malloc may contain garbage
|
||||
inst.IID = *iid // copy contents
|
||||
inst.Mutex = sync.Mutex{}
|
||||
inst.refs = 0
|
||||
|
||||
callbacksDeferralCompletedHandler.add(unsafe.Pointer(inst), callback)
|
||||
|
||||
// See the docs in the releaseChannelsDeferralCompletedHandler struct
|
||||
releaseChannelsDeferralCompletedHandler.acquire(unsafe.Pointer(inst))
|
||||
|
||||
inst.addRef()
|
||||
return inst
|
||||
}
|
||||
|
||||
func (r *DeferralCompletedHandler) GetIID() *ole.GUID {
|
||||
return &r.IID
|
||||
}
|
||||
|
||||
// addRef increments the reference counter by one
|
||||
func (r *DeferralCompletedHandler) addRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.refs++
|
||||
return r.refs
|
||||
}
|
||||
|
||||
// removeRef decrements the reference counter by one. If it was already zero, it will just return zero.
|
||||
func (r *DeferralCompletedHandler) removeRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
if r.refs > 0 {
|
||||
r.refs--
|
||||
}
|
||||
|
||||
return r.refs
|
||||
}
|
||||
|
||||
func (instance *DeferralCompletedHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr {
|
||||
|
||||
// See the quote above.
|
||||
if callback, ok := callbacksDeferralCompletedHandler.get(instancePtr); ok {
|
||||
callback(instance)
|
||||
}
|
||||
return ole.S_OK
|
||||
}
|
||||
|
||||
func (instance *DeferralCompletedHandler) AddRef() uintptr {
|
||||
return instance.addRef()
|
||||
}
|
||||
|
||||
func (instance *DeferralCompletedHandler) Release() uintptr {
|
||||
rem := instance.removeRef()
|
||||
if rem == 0 {
|
||||
// We're done.
|
||||
instancePtr := unsafe.Pointer(instance)
|
||||
callbacksDeferralCompletedHandler.delete(instancePtr)
|
||||
|
||||
// stop release channels used to avoid
|
||||
// https://github.com/golang/go/issues/55015
|
||||
releaseChannelsDeferralCompletedHandler.release(instancePtr)
|
||||
|
||||
kernel32.Free(unsafe.Pointer(instance.RawVTable))
|
||||
kernel32.Free(instancePtr)
|
||||
}
|
||||
return rem
|
||||
}
|
||||
|
||||
type deferralCompletedHandlerCallbacks struct {
|
||||
mu *sync.Mutex
|
||||
callbacks map[unsafe.Pointer]DeferralCompletedHandlerCallback
|
||||
}
|
||||
|
||||
func (m *deferralCompletedHandlerCallbacks) add(p unsafe.Pointer, v DeferralCompletedHandlerCallback) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.callbacks[p] = v
|
||||
}
|
||||
|
||||
func (m *deferralCompletedHandlerCallbacks) get(p unsafe.Pointer) (DeferralCompletedHandlerCallback, bool) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
v, ok := m.callbacks[p]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (m *deferralCompletedHandlerCallbacks) delete(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
delete(m.callbacks, p)
|
||||
}
|
||||
|
||||
// typedEventHandlerReleaseChannels keeps a map with channels
|
||||
// used to keep a goroutine alive during the lifecycle of this object.
|
||||
// This is required to avoid causing a deadlock error.
|
||||
// See this: https://github.com/golang/go/issues/55015
|
||||
type deferralCompletedHandlerReleaseChannels struct {
|
||||
mu *sync.Mutex
|
||||
chans map[unsafe.Pointer]chan struct{}
|
||||
}
|
||||
|
||||
func (m *deferralCompletedHandlerReleaseChannels) acquire(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
c := make(chan struct{})
|
||||
m.chans[p] = c
|
||||
|
||||
go func() {
|
||||
// we need a timer to trick the go runtime into
|
||||
// thinking there's still something going on here
|
||||
// but we are only really interested in <-c
|
||||
t := time.NewTimer(time.Minute)
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
t.Reset(time.Minute)
|
||||
case <-c:
|
||||
t.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (m *deferralCompletedHandlerReleaseChannels) release(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if c, ok := m.chans[p]; ok {
|
||||
close(c)
|
||||
delete(m.chans, p)
|
||||
}
|
||||
}
|
12
windows/foundation/eventregistrationtoken.go
Normal file
12
windows/foundation/eventregistrationtoken.go
Normal file
@ -0,0 +1,12 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
const SignatureEventRegistrationToken string = "struct(Windows.Foundation.EventRegistrationToken;i8)"
|
||||
|
||||
type EventRegistrationToken struct {
|
||||
Value int64
|
||||
}
|
76
windows/foundation/iasyncoperation.go
Normal file
76
windows/foundation/iasyncoperation.go
Normal file
@ -0,0 +1,76 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const GUIDIAsyncOperation string = "9fc2b0bb-e446-44e2-aa61-9cab8f636af2"
|
||||
const SignatureIAsyncOperation string = "{9fc2b0bb-e446-44e2-aa61-9cab8f636af2}"
|
||||
|
||||
type IAsyncOperation struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type IAsyncOperationVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
SetCompleted uintptr
|
||||
GetCompleted uintptr
|
||||
GetResults uintptr
|
||||
}
|
||||
|
||||
func (v *IAsyncOperation) VTable() *IAsyncOperationVtbl {
|
||||
return (*IAsyncOperationVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *IAsyncOperation) SetCompleted(handler *AsyncOperationCompletedHandler) error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().SetCompleted,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(handler)), // in AsyncOperationCompletedHandler
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *IAsyncOperation) GetCompleted() (*AsyncOperationCompletedHandler, error) {
|
||||
var out *AsyncOperationCompletedHandler
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetCompleted,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out AsyncOperationCompletedHandler
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (v *IAsyncOperation) GetResults() (unsafe.Pointer, error) {
|
||||
var out unsafe.Pointer
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetResults,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
43
windows/foundation/iclosable.go
Normal file
43
windows/foundation/iclosable.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const GUIDIClosable string = "30d5a829-7fa4-4026-83bb-d75bae4ea99e"
|
||||
const SignatureIClosable string = "{30d5a829-7fa4-4026-83bb-d75bae4ea99e}"
|
||||
|
||||
type IClosable struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type IClosableVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
Close uintptr
|
||||
}
|
||||
|
||||
func (v *IClosable) VTable() *IClosableVtbl {
|
||||
return (*IClosableVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *IClosable) Close() error {
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().Close,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return ole.NewError(hr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
45
windows/foundation/ireference.go
Normal file
45
windows/foundation/ireference.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
)
|
||||
|
||||
const GUIDIReference string = "61c17706-2d65-11e0-9ae8-d48564015472"
|
||||
const SignatureIReference string = "{61c17706-2d65-11e0-9ae8-d48564015472}"
|
||||
|
||||
type IReference struct {
|
||||
ole.IInspectable
|
||||
}
|
||||
|
||||
type IReferenceVtbl struct {
|
||||
ole.IInspectableVtbl
|
||||
|
||||
GetValue uintptr
|
||||
}
|
||||
|
||||
func (v *IReference) VTable() *IReferenceVtbl {
|
||||
return (*IReferenceVtbl)(unsafe.Pointer(v.RawVTable))
|
||||
}
|
||||
|
||||
func (v *IReference) GetValue() (unsafe.Pointer, error) {
|
||||
var out unsafe.Pointer
|
||||
hr, _, _ := syscall.SyscallN(
|
||||
v.VTable().GetValue,
|
||||
uintptr(unsafe.Pointer(v)), // this
|
||||
uintptr(unsafe.Pointer(&out)), // out unsafe.Pointer
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
return nil, ole.NewError(hr)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
208
windows/foundation/typedeventhandler.go
Normal file
208
windows/foundation/typedeventhandler.go
Normal file
@ -0,0 +1,208 @@
|
||||
// Code generated by winrt-go-gen. DO NOT EDIT.
|
||||
|
||||
//go:build windows
|
||||
|
||||
//nolint:all
|
||||
package foundation
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-ole/go-ole"
|
||||
"github.com/saltosystems/winrt-go/internal/delegate"
|
||||
"github.com/saltosystems/winrt-go/internal/kernel32"
|
||||
)
|
||||
|
||||
const GUIDTypedEventHandler string = "9de1c534-6ae1-11e0-84e1-18a905bcc53f"
|
||||
const SignatureTypedEventHandler string = "delegate({9de1c534-6ae1-11e0-84e1-18a905bcc53f})"
|
||||
|
||||
type TypedEventHandler struct {
|
||||
ole.IUnknown
|
||||
sync.Mutex
|
||||
refs uintptr
|
||||
IID ole.GUID
|
||||
}
|
||||
|
||||
type TypedEventHandlerVtbl struct {
|
||||
ole.IUnknownVtbl
|
||||
Invoke uintptr
|
||||
}
|
||||
|
||||
type TypedEventHandlerCallback func(instance *TypedEventHandler, sender unsafe.Pointer, args unsafe.Pointer)
|
||||
|
||||
var callbacksTypedEventHandler = &typedEventHandlerCallbacks{
|
||||
mu: &sync.Mutex{},
|
||||
callbacks: make(map[unsafe.Pointer]TypedEventHandlerCallback),
|
||||
}
|
||||
|
||||
var releaseChannelsTypedEventHandler = &typedEventHandlerReleaseChannels{
|
||||
mu: &sync.Mutex{},
|
||||
chans: make(map[unsafe.Pointer]chan struct{}),
|
||||
}
|
||||
|
||||
func NewTypedEventHandler(iid *ole.GUID, callback TypedEventHandlerCallback) *TypedEventHandler {
|
||||
// create type instance
|
||||
size := unsafe.Sizeof(*(*TypedEventHandler)(nil))
|
||||
instPtr := kernel32.Malloc(size)
|
||||
inst := (*TypedEventHandler)(instPtr)
|
||||
|
||||
// get the callbacks for the VTable
|
||||
callbacks := delegate.RegisterCallbacks(instPtr, inst)
|
||||
|
||||
// the VTable should also be allocated in the heap
|
||||
sizeVTable := unsafe.Sizeof(*(*TypedEventHandlerVtbl)(nil))
|
||||
vTablePtr := kernel32.Malloc(sizeVTable)
|
||||
|
||||
inst.RawVTable = (*interface{})(vTablePtr)
|
||||
|
||||
vTable := (*TypedEventHandlerVtbl)(vTablePtr)
|
||||
vTable.IUnknownVtbl = ole.IUnknownVtbl{
|
||||
QueryInterface: callbacks.QueryInterface,
|
||||
AddRef: callbacks.AddRef,
|
||||
Release: callbacks.Release,
|
||||
}
|
||||
vTable.Invoke = callbacks.Invoke
|
||||
|
||||
// Initialize all properties: the malloc may contain garbage
|
||||
inst.IID = *iid // copy contents
|
||||
inst.Mutex = sync.Mutex{}
|
||||
inst.refs = 0
|
||||
|
||||
callbacksTypedEventHandler.add(unsafe.Pointer(inst), callback)
|
||||
|
||||
// See the docs in the releaseChannelsTypedEventHandler struct
|
||||
releaseChannelsTypedEventHandler.acquire(unsafe.Pointer(inst))
|
||||
|
||||
inst.addRef()
|
||||
return inst
|
||||
}
|
||||
|
||||
func (r *TypedEventHandler) GetIID() *ole.GUID {
|
||||
return &r.IID
|
||||
}
|
||||
|
||||
// addRef increments the reference counter by one
|
||||
func (r *TypedEventHandler) addRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
r.refs++
|
||||
return r.refs
|
||||
}
|
||||
|
||||
// removeRef decrements the reference counter by one. If it was already zero, it will just return zero.
|
||||
func (r *TypedEventHandler) removeRef() uintptr {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
if r.refs > 0 {
|
||||
r.refs--
|
||||
}
|
||||
|
||||
return r.refs
|
||||
}
|
||||
|
||||
func (instance *TypedEventHandler) Invoke(instancePtr, rawArgs0, rawArgs1, rawArgs2, rawArgs3, rawArgs4, rawArgs5, rawArgs6, rawArgs7, rawArgs8 unsafe.Pointer) uintptr {
|
||||
senderPtr := rawArgs0
|
||||
argsPtr := rawArgs1
|
||||
|
||||
// See the quote above.
|
||||
sender := (unsafe.Pointer)(senderPtr)
|
||||
args := (unsafe.Pointer)(argsPtr)
|
||||
if callback, ok := callbacksTypedEventHandler.get(instancePtr); ok {
|
||||
callback(instance, sender, args)
|
||||
}
|
||||
return ole.S_OK
|
||||
}
|
||||
|
||||
func (instance *TypedEventHandler) AddRef() uintptr {
|
||||
return instance.addRef()
|
||||
}
|
||||
|
||||
func (instance *TypedEventHandler) Release() uintptr {
|
||||
rem := instance.removeRef()
|
||||
if rem == 0 {
|
||||
// We're done.
|
||||
instancePtr := unsafe.Pointer(instance)
|
||||
callbacksTypedEventHandler.delete(instancePtr)
|
||||
|
||||
// stop release channels used to avoid
|
||||
// https://github.com/golang/go/issues/55015
|
||||
releaseChannelsTypedEventHandler.release(instancePtr)
|
||||
|
||||
kernel32.Free(unsafe.Pointer(instance.RawVTable))
|
||||
kernel32.Free(instancePtr)
|
||||
}
|
||||
return rem
|
||||
}
|
||||
|
||||
type typedEventHandlerCallbacks struct {
|
||||
mu *sync.Mutex
|
||||
callbacks map[unsafe.Pointer]TypedEventHandlerCallback
|
||||
}
|
||||
|
||||
func (m *typedEventHandlerCallbacks) add(p unsafe.Pointer, v TypedEventHandlerCallback) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
m.callbacks[p] = v
|
||||
}
|
||||
|
||||
func (m *typedEventHandlerCallbacks) get(p unsafe.Pointer) (TypedEventHandlerCallback, bool) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
v, ok := m.callbacks[p]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
func (m *typedEventHandlerCallbacks) delete(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
delete(m.callbacks, p)
|
||||
}
|
||||
|
||||
// typedEventHandlerReleaseChannels keeps a map with channels
|
||||
// used to keep a goroutine alive during the lifecycle of this object.
|
||||
// This is required to avoid causing a deadlock error.
|
||||
// See this: https://github.com/golang/go/issues/55015
|
||||
type typedEventHandlerReleaseChannels struct {
|
||||
mu *sync.Mutex
|
||||
chans map[unsafe.Pointer]chan struct{}
|
||||
}
|
||||
|
||||
func (m *typedEventHandlerReleaseChannels) acquire(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
c := make(chan struct{})
|
||||
m.chans[p] = c
|
||||
|
||||
go func() {
|
||||
// we need a timer to trick the go runtime into
|
||||
// thinking there's still something going on here
|
||||
// but we are only really interested in <-c
|
||||
t := time.NewTimer(time.Minute)
|
||||
for {
|
||||
select {
|
||||
case <-t.C:
|
||||
t.Reset(time.Minute)
|
||||
case <-c:
|
||||
t.Stop()
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (m *typedEventHandlerReleaseChannels) release(p unsafe.Pointer) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
if c, ok := m.chans[p]; ok {
|
||||
close(c)
|
||||
delete(m.chans, p)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user