Skip to content

Commit fe5e551

Browse files
committed
Fix violation of cgo pointer rules
1 parent 0ece357 commit fe5e551

16 files changed

+120
-121
lines changed

shared_directory_arm64.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ const (
3333
)
3434

3535
//export linuxInstallRosettaWithCompletionHandler
36-
func linuxInstallRosettaWithCompletionHandler(cgoHandlerPtr, errPtr unsafe.Pointer) {
37-
cgoHandler := *(*cgo.Handle)(cgoHandlerPtr)
36+
func linuxInstallRosettaWithCompletionHandler(cgoHandleUintptr C.uintptr_t, errPtr unsafe.Pointer) {
37+
cgoHandle := cgo.Handle(cgoHandleUintptr)
3838

39-
handler := cgoHandler.Value().(func(error))
39+
handler := cgoHandle.Value().(func(error))
4040

4141
if err := newNSError(errPtr); err != nil {
4242
handler(err)
@@ -89,10 +89,10 @@ func LinuxRosettaDirectoryShareInstallRosetta() error {
8989
return err
9090
}
9191
errCh := make(chan error, 1)
92-
cgoHandler := cgo.NewHandle(func(err error) {
92+
cgoHandle := cgo.NewHandle(func(err error) {
9393
errCh <- err
9494
})
95-
C.linuxInstallRosetta(unsafe.Pointer(&cgoHandler))
95+
C.linuxInstallRosetta(C.uintptr_t(cgoHandle))
9696
return <-errCh
9797
}
9898

socket.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -97,17 +97,17 @@ func (v *VirtioSocketDevice) Listen(port uint32) (*VirtioSocketListener, error)
9797

9898
ch := make(chan connResults, 1) // should I increase more caps?
9999

100-
handler := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) {
100+
handle := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) {
101101
ch <- connResults{conn, err}
102102
})
103103
ptr := C.newVZVirtioSocketListener(
104-
unsafe.Pointer(&handler),
104+
C.uintptr_t(handle),
105105
)
106106
listener := &VirtioSocketListener{
107107
pointer: objc.NewPointer(ptr),
108108
vsockDevice: v,
109109
port: port,
110-
handler: handler,
110+
handle: handle,
111111
acceptch: ch,
112112
}
113113

@@ -122,10 +122,10 @@ func (v *VirtioSocketDevice) Listen(port uint32) (*VirtioSocketListener, error)
122122
}
123123

124124
//export connectionHandler
125-
func connectionHandler(connPtr, errPtr, cgoHandlerPtr unsafe.Pointer) {
126-
cgoHandler := *(*cgo.Handle)(cgoHandlerPtr)
127-
handler := cgoHandler.Value().(func(*VirtioSocketConnection, error))
128-
defer cgoHandler.Delete()
125+
func connectionHandler(connPtr, errPtr unsafe.Pointer, cgoHandleUintptr C.uintptr_t) {
126+
cgoHandle := cgo.Handle(cgoHandleUintptr)
127+
handler := cgoHandle.Value().(func(*VirtioSocketConnection, error))
128+
defer cgoHandle.Delete()
129129
// see: startHandler
130130
if err := newNSError(errPtr); err != nil {
131131
handler(nil, err)
@@ -144,15 +144,15 @@ func connectionHandler(connPtr, errPtr, cgoHandlerPtr unsafe.Pointer) {
144144
// see: https://developer.apple.com/documentation/virtualization/vzvirtiosocketdevice/3656677-connecttoport?language=objc
145145
func (v *VirtioSocketDevice) Connect(port uint32) (*VirtioSocketConnection, error) {
146146
ch := make(chan connResults, 1)
147-
cgoHandler := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) {
147+
cgoHandle := cgo.NewHandle(func(conn *VirtioSocketConnection, err error) {
148148
ch <- connResults{conn, err}
149149
close(ch)
150150
})
151151
C.VZVirtioSocketDevice_connectToPort(
152152
objc.Ptr(v),
153153
v.dispatchQueue,
154154
C.uint32_t(port),
155-
unsafe.Pointer(&cgoHandler),
155+
C.uintptr_t(cgoHandle),
156156
)
157157
result := <-ch
158158
runtime.KeepAlive(v)
@@ -170,7 +170,7 @@ type connResults struct {
170170
type VirtioSocketListener struct {
171171
*pointer
172172
vsockDevice *VirtioSocketDevice
173-
handler cgo.Handle
173+
handle cgo.Handle
174174
port uint32
175175
acceptch chan connResults
176176
closeOnce sync.Once
@@ -197,7 +197,7 @@ func (v *VirtioSocketListener) Close() error {
197197
v.vsockDevice.dispatchQueue,
198198
C.uint32_t(v.port),
199199
)
200-
v.handler.Delete()
200+
v.handle.Delete()
201201
})
202202
return nil
203203
}
@@ -226,9 +226,9 @@ func (a *VirtioSocketListenerAddr) Network() string { return "vsock" }
226226
func (a *VirtioSocketListenerAddr) String() string { return fmt.Sprintf("%d:%d", a.CID, a.Port) }
227227

228228
//export shouldAcceptNewConnectionHandler
229-
func shouldAcceptNewConnectionHandler(cgoHandlerPtr, connPtr, devicePtr unsafe.Pointer) C.bool {
230-
cgoHandler := *(*cgo.Handle)(cgoHandlerPtr)
231-
handler := cgoHandler.Value().(func(*VirtioSocketConnection, error))
229+
func shouldAcceptNewConnectionHandler(cgoHandleUintptr C.uintptr_t, connPtr, devicePtr unsafe.Pointer) C.bool {
230+
cgoHandle := cgo.Handle(cgoHandleUintptr)
231+
handler := cgoHandle.Value().(func(*VirtioSocketConnection, error))
232232

233233
// see: startHandler
234234
conn, err := newVirtioSocketConnection(connPtr)

virtualization.go

+31-31
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ type VirtualMachine struct {
7575

7676
*pointer
7777
dispatchQueue unsafe.Pointer
78-
stateHandle *machineState
78+
machineState *machineState
7979

8080
finalizeOnce sync.Once
8181
}
@@ -103,28 +103,28 @@ func NewVirtualMachine(config *VirtualMachineConfiguration) (*VirtualMachine, er
103103
cs := (*char)(objc.GetUUID())
104104
dispatchQueue := C.makeDispatchQueue(cs.CString())
105105

106-
stateHandle := &machineState{
106+
machineState := &machineState{
107107
state: VirtualMachineState(0),
108108
stateNotify: infinity.NewChannel[VirtualMachineState](),
109109
}
110110

111-
stateHandlePtr := cgo.NewHandle(stateHandle)
111+
stateHandle := cgo.NewHandle(machineState)
112112
v := &VirtualMachine{
113113
id: cs.String(),
114114
pointer: objc.NewPointer(
115115
C.newVZVirtualMachineWithDispatchQueue(
116116
objc.Ptr(config),
117117
dispatchQueue,
118-
unsafe.Pointer(&stateHandlePtr),
118+
C.uintptr_t(stateHandle),
119119
),
120120
),
121121
dispatchQueue: dispatchQueue,
122-
stateHandle: stateHandle,
122+
machineState: machineState,
123123
}
124124

125125
objc.SetFinalizer(v, func(self *VirtualMachine) {
126126
self.finalize()
127-
stateHandlePtr.Delete()
127+
stateHandle.Delete()
128128
})
129129
return v, nil
130130
}
@@ -155,11 +155,11 @@ func (v *VirtualMachine) SocketDevices() []*VirtioSocketDevice {
155155
}
156156

157157
//export changeStateOnObserver
158-
func changeStateOnObserver(newStateRaw C.int, cgoHandlerPtr unsafe.Pointer) {
159-
stateHandler := *(*cgo.Handle)(cgoHandlerPtr)
158+
func changeStateOnObserver(newStateRaw C.int, cgoHandleUintptr C.uintptr_t) {
159+
stateHandle := cgo.Handle(cgoHandleUintptr)
160160
// I expected it will not cause panic.
161161
// if caused panic, that's unexpected behavior.
162-
v, _ := stateHandler.Value().(*machineState)
162+
v, _ := stateHandle.Value().(*machineState)
163163
v.mu.Lock()
164164
newState := VirtualMachineState(newStateRaw)
165165
v.state = newState
@@ -169,16 +169,16 @@ func changeStateOnObserver(newStateRaw C.int, cgoHandlerPtr unsafe.Pointer) {
169169

170170
// State represents execution state of the virtual machine.
171171
func (v *VirtualMachine) State() VirtualMachineState {
172-
v.stateHandle.mu.RLock()
173-
defer v.stateHandle.mu.RUnlock()
174-
return v.stateHandle.state
172+
v.machineState.mu.RLock()
173+
defer v.machineState.mu.RUnlock()
174+
return v.machineState.state
175175
}
176176

177177
// StateChangedNotify gets notification is changed execution state of the virtual machine.
178178
func (v *VirtualMachine) StateChangedNotify() <-chan VirtualMachineState {
179-
v.stateHandle.mu.RLock()
180-
defer v.stateHandle.mu.RUnlock()
181-
return v.stateHandle.stateNotify.Out()
179+
v.machineState.mu.RLock()
180+
defer v.machineState.mu.RUnlock()
181+
return v.machineState.stateNotify.Out()
182182
}
183183

184184
// CanStart returns true if the machine is in a state that can be started.
@@ -213,10 +213,10 @@ func (v *VirtualMachine) CanStop() bool {
213213
}
214214

215215
//export virtualMachineCompletionHandler
216-
func virtualMachineCompletionHandler(cgoHandlerPtr, errPtr unsafe.Pointer) {
217-
cgoHandler := *(*cgo.Handle)(cgoHandlerPtr)
216+
func virtualMachineCompletionHandler(cgoHandleUintptr C.uintptr_t, errPtr unsafe.Pointer) {
217+
cgoHandle := cgo.Handle(cgoHandleUintptr)
218218

219-
handler := cgoHandler.Value().(func(error))
219+
handler := cgoHandle.Value().(func(error))
220220

221221
if err := newNSError(errPtr); err != nil {
222222
handler(err)
@@ -255,18 +255,18 @@ func (v *VirtualMachine) Start(opts ...VirtualMachineStartOption) error {
255255
}
256256

257257
h, errCh := makeHandler()
258-
handler := cgo.NewHandle(h)
259-
defer handler.Delete()
258+
handle := cgo.NewHandle(h)
259+
defer handle.Delete()
260260

261261
if o.macOSVirtualMachineStartOptionsPtr != nil {
262262
C.startWithOptionsCompletionHandler(
263263
objc.Ptr(v),
264264
v.dispatchQueue,
265265
o.macOSVirtualMachineStartOptionsPtr,
266-
unsafe.Pointer(&handler),
266+
C.uintptr_t(handle),
267267
)
268268
} else {
269-
C.startWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler))
269+
C.startWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, C.uintptr_t(handle))
270270
}
271271
return <-errCh
272272
}
@@ -276,9 +276,9 @@ func (v *VirtualMachine) Start(opts ...VirtualMachineStartOption) error {
276276
// If you want to listen status change events, use the "StateChangedNotify" method.
277277
func (v *VirtualMachine) Pause() error {
278278
h, errCh := makeHandler()
279-
handler := cgo.NewHandle(h)
280-
defer handler.Delete()
281-
C.pauseWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler))
279+
handle := cgo.NewHandle(h)
280+
defer handle.Delete()
281+
C.pauseWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, C.uintptr_t(handle))
282282
return <-errCh
283283
}
284284

@@ -287,9 +287,9 @@ func (v *VirtualMachine) Pause() error {
287287
// If you want to listen status change events, use the "StateChangedNotify" method.
288288
func (v *VirtualMachine) Resume() error {
289289
h, errCh := makeHandler()
290-
handler := cgo.NewHandle(h)
291-
defer handler.Delete()
292-
C.resumeWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler))
290+
handle := cgo.NewHandle(h)
291+
defer handle.Delete()
292+
C.resumeWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, C.uintptr_t(handle))
293293
return <-errCh
294294
}
295295

@@ -322,9 +322,9 @@ func (v *VirtualMachine) Stop() error {
322322
return err
323323
}
324324
h, errCh := makeHandler()
325-
handler := cgo.NewHandle(h)
326-
defer handler.Delete()
327-
C.stopWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, unsafe.Pointer(&handler))
325+
handle := cgo.NewHandle(h)
326+
defer handle.Delete()
327+
C.stopWithCompletionHandler(objc.Ptr(v), v.dispatchQueue, C.uintptr_t(handle))
328328
return <-errCh
329329
}
330330

virtualization_11.h

+11-11
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
#import <Virtualization/Virtualization.h>
1111

1212
/* exported from cgo */
13-
void connectionHandler(void *connection, void *err, void *cgoHandlerPtr);
14-
void changeStateOnObserver(int state, void *cgoHandler);
15-
bool shouldAcceptNewConnectionHandler(void *cgoHandler, void *connection, void *socketDevice);
13+
void connectionHandler(void *connection, void *err, uintptr_t cgoHandle);
14+
void changeStateOnObserver(int state, uintptr_t cgoHandle);
15+
bool shouldAcceptNewConnectionHandler(uintptr_t cgoHandle, void *connection, void *socketDevice);
1616

1717
@interface Observer : NSObject
1818
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
@@ -21,13 +21,13 @@ bool shouldAcceptNewConnectionHandler(void *cgoHandler, void *connection, void *
2121
@interface ObservableVZVirtualMachine : VZVirtualMachine
2222
- (instancetype)initWithConfiguration:(VZVirtualMachineConfiguration *)configuration
2323
queue:(dispatch_queue_t)queue
24-
statusHandler:(void *)statusHandler;
24+
statusUpdateHandle:(uintptr_t)statusUpdateHandle;
2525
- (void)dealloc;
2626
@end
2727

2828
/* VZVirtioSocketListener */
2929
@interface VZVirtioSocketListenerDelegateImpl : NSObject <VZVirtioSocketListenerDelegate>
30-
- (instancetype)initWithHandler:(void *)cgoHandler;
30+
- (instancetype)initWithHandle:(uintptr_t)cgoHandle;
3131
- (BOOL)listener:(VZVirtioSocketListener *)listener shouldAcceptNewConnection:(VZVirtioSocketConnection *)connection fromSocketDevice:(VZVirtioSocketDevice *)socketDevice;
3232
@end
3333

@@ -77,18 +77,18 @@ void *newVZVirtioSocketDeviceConfiguration();
7777
void *newVZMACAddress(const char *macAddress);
7878
void *newRandomLocallyAdministeredVZMACAddress();
7979
const char *getVZMACAddressString(void *macAddress);
80-
void *newVZVirtioSocketListener(void *cgoHandlerPtr);
80+
void *newVZVirtioSocketListener(uintptr_t cgoHandle);
8181
void *VZVirtualMachine_socketDevices(void *machine);
8282
void VZVirtioSocketDevice_setSocketListenerForPort(void *socketDevice, void *vmQueue, void *listener, uint32_t port);
8383
void VZVirtioSocketDevice_removeSocketListenerForPort(void *socketDevice, void *vmQueue, uint32_t port);
84-
void VZVirtioSocketDevice_connectToPort(void *socketDevice, void *vmQueue, uint32_t port, void *cgoHandlerPtr);
84+
void VZVirtioSocketDevice_connectToPort(void *socketDevice, void *vmQueue, uint32_t port, uintptr_t cgoHandle);
8585

8686
/* VirtualMachine */
87-
void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, void *statusHandler);
87+
void *newVZVirtualMachineWithDispatchQueue(void *config, void *queue, uintptr_t cgoHandle);
8888
bool requestStopVirtualMachine(void *machine, void *queue, void **error);
89-
void startWithCompletionHandler(void *machine, void *queue, void *completionHandler);
90-
void pauseWithCompletionHandler(void *machine, void *queue, void *completionHandler);
91-
void resumeWithCompletionHandler(void *machine, void *queue, void *completionHandler);
89+
void startWithCompletionHandler(void *machine, void *queue, uintptr_t cgoHandle);
90+
void pauseWithCompletionHandler(void *machine, void *queue, uintptr_t cgoHandle);
91+
void resumeWithCompletionHandler(void *machine, void *queue, uintptr_t cgoHandle);
9292
bool vmCanStart(void *machine, void *queue);
9393
bool vmCanPause(void *machine, void *queue);
9494
bool vmCanResume(void *machine, void *queue);

0 commit comments

Comments
 (0)