fix: fixed memory leak in the Sensors module on Apple Silicon (#417)

This commit is contained in:
Serhiy Mytrovtsiy
2021-05-08 20:38:26 +02:00
parent a5ac0d25dc
commit c21508d223
5 changed files with 66 additions and 30 deletions

View File

@@ -21,11 +21,20 @@ typedef double IOHIDFloat;
typedef float IOHIDFloat;
#endif
#define IOHIDEventFieldBase(type) (type << 16)
#define kIOHIDEventTypeTemperature 15
#define kIOHIDEventTypePower 25
typedef enum AppleSiliconSensorType: NSUInteger {
temperature=1,
current=2,
voltage=3,
} AppleSiliconSensorType;
IOHIDEventSystemClientRef IOHIDEventSystemClientCreate(CFAllocatorRef allocator);
int IOHIDEventSystemClientSetMatching(IOHIDEventSystemClientRef client, CFDictionaryRef match);
IOHIDEventRef IOHIDServiceClientCopyEvent(IOHIDServiceClientRef, int64_t , int32_t, int64_t);
CFStringRef IOHIDServiceClientCopyProperty(IOHIDServiceClientRef service, CFStringRef property);
IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, int32_t field);
NSDictionary*AppleSiliconSensors(int page, int usage, int32_t type);

47
Modules/Sensors/reader.m Normal file
View File

@@ -0,0 +1,47 @@
//
// reader.m
// Sensors
//
// Created by Serhiy Mytrovtsiy on 06/05/2021.
// Using Swift 5.0.
// Running on macOS 10.15.
//
// Copyright © 2021 Serhiy Mytrovtsiy. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "bridge.h"
NSDictionary*AppleSiliconSensors(int32_t page, int32_t usage, int32_t type) {
NSDictionary* dictionary = @{@"PrimaryUsagePage":@(page),@"PrimaryUsage":@(usage)};
IOHIDEventSystemClientRef system = IOHIDEventSystemClientCreate(kCFAllocatorDefault);
IOHIDEventSystemClientSetMatching(system, (__bridge CFDictionaryRef)dictionary);
CFArrayRef services = IOHIDEventSystemClientCopyServices(system);
if (services == nil) {
return nil;
}
NSMutableDictionary*dict = [NSMutableDictionary dictionary];
for (int i = 0; i < CFArrayGetCount(services); i++) {
IOHIDServiceClientRef service = (IOHIDServiceClientRef)CFArrayGetValueAtIndex(services, i);
NSString* name = CFBridgingRelease(IOHIDServiceClientCopyProperty(service, CFSTR("Product")));
IOHIDEventRef event = IOHIDServiceClientCopyEvent(service, type, 0, 0);
if (event == nil) {
continue;
}
if (name && event) {
double value = IOHIDEventGetFloatValue(event, IOHIDEventFieldBase(type));
dict[name]=@(value);
}
CFRelease(event);
}
CFRelease(services);
CFRelease(system);
return dict;
}

View File

@@ -113,8 +113,8 @@ internal class AppleSilicon_SensorsReader: SensorsReader {
}
private func fetch(type: SensorType) {
var page: Int = 0
var usage: Int = 0
var page: Int32 = 0
var usage: Int32 = 0
var eventType: Int32 = kIOHIDEventTypeTemperature
// usagePage:
@@ -147,33 +147,9 @@ internal class AppleSilicon_SensorsReader: SensorsReader {
case .fan: break
}
guard let client = IOHIDEventSystemClientCreate(kCFAllocatorDefault) else {
return
}
let system: IOHIDEventSystemClient = client.takeRetainedValue()
let dict = createDeviceMatchingDictionary(usagePage: page, usage: usage)
IOHIDEventSystemClientSetMatching(system, dict)
guard let services: CFArray = IOHIDEventSystemClientCopyServices(system) else {
return
}
for i in 0..<CFArrayGetCount(services) {
var value = CFArrayGetValueAtIndex(services, i)
withUnsafePointer(to: &value) { rawPtr in
let service = UnsafeRawPointer(rawPtr).assumingMemoryBound(to: IOHIDServiceClientRef.self)
let namePtr: Unmanaged<CFString>? = IOHIDServiceClientCopyProperty(service.pointee, "Product" as CFString)
guard let nameCF = namePtr?.takeRetainedValue() else {
return
}
let name = nameCF as String
if let eventPtr: IOHIDEventRef = IOHIDServiceClientCopyEvent(service.pointee, Int64(eventType), 0, 0) {
let value = IOHIDEventGetFloatValue(eventPtr, eventType << 16)
if let list = AppleSiliconSensors(page, usage, eventType) {
list.forEach { (key, value) in
if let name = key as? String, let value = value as? Double {
if self.cache.keys.contains(name) {
self.cache[name]?.value = value
} else {

View File

@@ -99,6 +99,7 @@
9AB14B7A248CEF4900DC6731 /* config.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9ABFF904248BEC0B00C9041A /* config.plist */; };
9AB1572E25407F7B00671260 /* ModuleKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AABEADD243FB13500668CB0 /* ModuleKit.framework */; };
9AB1573D25407F7E00671260 /* StatsKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0C82DA24460F7200FAE3D4 /* StatsKit.framework */; };
9AB6D03926447CAA003215A5 /* reader.m in Sources */ = {isa = PBXBuildFile; fileRef = 9AB6D03826447CAA003215A5 /* reader.m */; };
9AB7FD7C246B48DB00387FDA /* settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AB7FD7B246B48DB00387FDA /* settings.swift */; };
9ABFF8FD248BEBCB00C9041A /* Battery.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ABFF8F6248BEBCB00C9041A /* Battery.framework */; };
9ABFF8FE248BEBCB00C9041A /* Battery.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9ABFF8F6248BEBCB00C9041A /* Battery.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@@ -465,6 +466,7 @@
9AABEAE9243FB15E00668CB0 /* module.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = module.swift; sourceTree = "<group>"; };
9AABEB79243FD26200668CB0 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
9AABEB7D243FDEF100668CB0 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
9AB6D03826447CAA003215A5 /* reader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = reader.m; sourceTree = "<group>"; };
9AB7FD7B246B48DB00387FDA /* settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = settings.swift; sourceTree = "<group>"; };
9ABFF8F6248BEBCB00C9041A /* Battery.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Battery.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9ABFF8F9248BEBCB00C9041A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -863,6 +865,7 @@
9AE29AEC249A50960071B02D /* Info.plist */,
9AE29AF4249A52870071B02D /* config.plist */,
9A3616E82613C3D400D657B6 /* bridge.h */,
9AB6D03826447CAA003215A5 /* reader.m */,
);
path = Sensors;
sourceTree = "<group>";
@@ -1563,6 +1566,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9AB6D03926447CAA003215A5 /* reader.m in Sources */,
9AE29AFB249A53DC0071B02D /* readers.swift in Sources */,
9AE29AFC249A53DC0071B02D /* values.swift in Sources */,
9A58DE9E24B363D800716A9F /* popup.swift in Sources */,

View File

@@ -17,7 +17,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>240</string>
<string>241</string>
<key>Description</key>
<string>Simple macOS system monitor in your menu bar</string>
<key>LSApplicationCategoryType</key>