@@ -17,26 +17,133 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
17
17
}
18
18
@end
19
19
20
+ @implementation VZVirtualMachineDelegateWrapper
21
+ - (instancetype )init
22
+ {
23
+ self = [super init ];
24
+ if (self) {
25
+ _delegates = [NSHashTable weakObjectsHashTable ];
26
+ }
27
+ return self;
28
+ }
29
+
30
+ - (void )addDelegate : (id <VZVirtualMachineDelegate>)delegate
31
+ {
32
+ [self .delegates addObject: delegate];
33
+ }
34
+
35
+ - (void )guestDidStopVirtualMachine : (VZVirtualMachine *)virtualMachine
36
+ {
37
+ for (id <VZVirtualMachineDelegate> delegate in self.delegates ) {
38
+ if ([delegate respondsToSelector: @selector (guestDidStopVirtualMachine: )]) {
39
+ [delegate guestDidStopVirtualMachine: virtualMachine];
40
+ }
41
+ }
42
+ }
43
+
44
+ - (void )virtualMachine : (VZVirtualMachine *)virtualMachine didStopWithError : (NSError *)error
45
+ {
46
+ for (id <VZVirtualMachineDelegate> delegate in self.delegates ) {
47
+ if ([delegate respondsToSelector: @selector (virtualMachine:didStopWithError: )]) {
48
+ [delegate virtualMachine: virtualMachine didStopWithError: error];
49
+ }
50
+ }
51
+ }
52
+
53
+ - (void )virtualMachine : (VZVirtualMachine *)virtualMachine networkDevice : (VZNetworkDevice *)networkDevice
54
+ attachmentWasDisconnectedWithError : (NSError *)error
55
+ {
56
+ for (id <VZVirtualMachineDelegate> delegate in self.delegates ) {
57
+ if ([delegate respondsToSelector: @selector (virtualMachine:networkDevice:attachmentWasDisconnectedWithError: )]) {
58
+ [delegate virtualMachine: virtualMachine networkDevice: networkDevice attachmentWasDisconnectedWithError: error];
59
+ }
60
+ }
61
+ }
62
+ @end
63
+
64
+ @implementation VZVirtualMachineNetworkDeviceErrorHandler {
65
+ uintptr_t _cgoHandle;
66
+ }
67
+
68
+ // TODO(codehex): Support the conditions under which the attachmentWasDisconnectedWithError method
69
+ // is executed as soon as they are known.
70
+ - (instancetype )initWithHandle : (uintptr_t )cgoHandle
71
+ {
72
+ self = [super init ];
73
+ if (self) {
74
+ _cgoHandle = cgoHandle;
75
+ }
76
+ return self;
77
+ }
78
+
79
+ - (void )virtualMachine : (VZVirtualMachine *)virtualMachine
80
+ networkDevice : (VZNetworkDevice *)networkDevice
81
+ attachmentWasDisconnectedWithError : (NSError *)error
82
+ {
83
+ NSProcessInfo *processInfo = [NSProcessInfo processInfo ];
84
+ NSString *processName = [processInfo processName ];
85
+ NSString *osVersion = [processInfo operatingSystemVersionString ];
86
+ struct utsname systemInfo;
87
+ uname (&systemInfo);
88
+ NSString *architecture = [NSString stringWithCString: systemInfo.machine
89
+ encoding: NSUTF8StringEncoding];
90
+
91
+ NSLog (
92
+ @" If you see this message, please report the information about the OS (including the version) that you are running on the VM, "
93
+ @" along with the information displayed below, to https://github.com/Code-Hex/vz/issues.\n "
94
+ @" Process Information:\n "
95
+ @" Name: %@ \n "
96
+ @" macOS: %@ , %@ \n "
97
+ @" networkDevice: %@ \n "
98
+ @" networkDevice attachment: %@ \n "
99
+ @" attachmentWasDisconnectedWithError: %@ " ,
100
+ processName,
101
+ osVersion,
102
+ architecture,
103
+ networkDevice,
104
+ networkDevice.attachment ,
105
+ error);
106
+ }
107
+ @end
108
+
20
109
@implementation ObservableVZVirtualMachine {
21
110
Observer *_observer;
111
+ VZVirtualMachineDelegateWrapper *_delegateWrapper;
22
112
};
23
113
- (instancetype )initWithConfiguration : (VZVirtualMachineConfiguration *)configuration
24
114
queue : (dispatch_queue_t )queue
25
115
statusUpdateHandle : (uintptr_t )statusUpdateHandle
26
116
{
27
117
self = [super initWithConfiguration: configuration queue: queue];
28
- _observer = [[Observer alloc ] init ];
29
- [self addObserver: _observer
30
- forKeyPath: @" state"
31
- options: NSKeyValueObservingOptionNew
32
- context: (void *)statusUpdateHandle];
118
+ if (self) {
119
+ _observer = [[Observer alloc ] init ];
120
+ [self addObserver: _observer
121
+ forKeyPath: @" state"
122
+ options: NSKeyValueObservingOptionNew
123
+ context: (void *)statusUpdateHandle];
124
+ _delegateWrapper = [[VZVirtualMachineDelegateWrapper alloc ] init ];
125
+ [super setDelegate: _delegateWrapper];
126
+ }
33
127
return self;
34
128
}
35
129
130
+ - (void )setDelegate : (id <VZVirtualMachineDelegate>)delegate
131
+ {
132
+ if (delegate != _delegateWrapper) {
133
+ [_delegateWrapper addDelegate: delegate];
134
+ }
135
+ }
136
+
137
+ - (id <VZVirtualMachineDelegate>)delegate
138
+ {
139
+ return _delegateWrapper;
140
+ }
141
+
36
142
- (void )dealloc
37
143
{
38
144
[self removeObserver: _observer forKeyPath: @" state" ];
39
145
[_observer release ];
146
+ [_delegateWrapper release ];
40
147
[super dealloc ];
41
148
}
42
149
@end
@@ -48,7 +155,9 @@ @implementation VZVirtioSocketListenerDelegateImpl {
48
155
- (instancetype )initWithHandle : (uintptr_t )cgoHandle
49
156
{
50
157
self = [super init ];
51
- _cgoHandle = cgoHandle;
158
+ if (self) {
159
+ _cgoHandle = cgoHandle;
160
+ }
52
161
return self;
53
162
}
54
163
@@ -731,13 +840,15 @@ VZVirtioSocketConnectionFlat convertVZVirtioSocketConnection2Flat(void *connecti
731
840
Every operation on the virtual machine must be done on that queue. The callbacks and delegate methods are invoked on that queue.
732
841
If the queue is not serial, the behavior is undefined.
733
842
*/
734
- void *newVZVirtualMachineWithDispatchQueue (void *config, void *queue, uintptr_t cgoHandle )
843
+ void *newVZVirtualMachineWithDispatchQueue (void *config, void *queue, uintptr_t statusUpdateCgoHandle )
735
844
{
736
845
if (@available (macOS 11 , *)) {
737
846
ObservableVZVirtualMachine *vm = [[ObservableVZVirtualMachine alloc ]
738
847
initWithConfiguration: (VZVirtualMachineConfiguration *)config
739
848
queue: (dispatch_queue_t )queue
740
- statusUpdateHandle: cgoHandle];
849
+ statusUpdateHandle: statusUpdateCgoHandle];
850
+ VZVirtualMachineNetworkDeviceErrorHandler *delegate = [[[VZVirtualMachineNetworkDeviceErrorHandler alloc ] init ] autorelease ];
851
+ [vm setDelegate: delegate];
741
852
return vm;
742
853
}
743
854
0 commit comments