1
0
Fork 0

Work-around OS-X event-input shutdown crashes.

This commit is contained in:
James Turner 2017-01-09 16:54:15 +00:00
parent f61293a935
commit 9441f0d656
3 changed files with 47 additions and 18 deletions

View file

@ -321,9 +321,16 @@ FGEventInput::FGEventInput() :
FGEventInput::~FGEventInput() FGEventInput::~FGEventInput()
{ {
for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it )
delete (*it).second; }
input_devices.clear();
void FGEventInput::shutdown()
{
for (auto it : input_devices) {
it.second->Close();
delete it.second;
}
input_devices.clear();
} }
void FGEventInput::init( ) void FGEventInput::init( )
@ -339,9 +346,9 @@ void FGEventInput::postinit ()
void FGEventInput::update( double dt ) void FGEventInput::update( double dt )
{ {
// call each associated device's update() method for (auto it : input_devices) {
for( map<int,FGInputDevice*>::iterator it = input_devices.begin(); it != input_devices.end(); ++it ) it.second->update(dt);
(*it).second->update( dt ); }
} }
unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice ) unsigned FGEventInput::AddDevice( FGInputDevice * inputDevice )
@ -402,6 +409,7 @@ void FGEventInput::RemoveDevice( unsigned index )
FGInputDevice *inputDevice = input_devices[index]; FGInputDevice *inputDevice = input_devices[index];
if (inputDevice) { if (inputDevice) {
inputDevice->Close();
input_devices.erase(index); input_devices.erase(index);
delete inputDevice; delete inputDevice;

View file

@ -290,6 +290,7 @@ public:
virtual void init(); virtual void init();
virtual void postinit(); virtual void postinit();
virtual void update( double dt ); virtual void update( double dt );
virtual void shutdown() override;
const static unsigned MAX_DEVICES = 1000; const static unsigned MAX_DEVICES = 1000;
const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1; const static unsigned INVALID_DEVICE_INDEX = MAX_DEVICES + 1;

View file

@ -153,8 +153,8 @@ public:
virtual ~FGMacOSXInputDevice(); virtual ~FGMacOSXInputDevice();
void Open(); void Open() override;
void Close(); void Close() override;
virtual void update(double dt); virtual void update(double dt);
virtual const char *TranslateEventName(FGEventData &eventData); virtual const char *TranslateEventName(FGEventData &eventData);
@ -169,7 +169,7 @@ private:
void buildElementNameDictionary(); void buildElementNameDictionary();
std::string nameForHIDElement(IOHIDElementRef element) const; std::string nameForHIDElement(IOHIDElementRef element) const;
IOHIDDeviceRef _hid; IOHIDDeviceRef _hid;
IOHIDQueueRef _queue; IOHIDQueueRef _queue;
FGMacOSXEventInputPrivate* _subsystem; FGMacOSXEventInputPrivate* _subsystem;
@ -227,6 +227,11 @@ void FGMacOSXEventInput::postinit()
void FGMacOSXEventInput::shutdown() void FGMacOSXEventInput::shutdown()
{ {
FGEventInput::shutdown();
IOHIDManagerRegisterDeviceMatchingCallback(d->hidManager, nullptr, nullptr);
IOHIDManagerRegisterDeviceRemovalCallback(d->hidManager, nullptr, nullptr);
IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone); IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRelease(d->hidManager); CFRelease(d->hidManager);
@ -259,6 +264,12 @@ void FGMacOSXEventInputPrivate::matchedDevice(IOHIDDeviceRef device)
void FGMacOSXEventInputPrivate::removedDevice(IOHIDDeviceRef device) void FGMacOSXEventInputPrivate::removedDevice(IOHIDDeviceRef device)
{ {
std::string productName = getDeviceStringProperty(device, CFSTR(kIOHIDProductKey));
std::string manufacturer = getDeviceStringProperty(device, CFSTR(kIOHIDManufacturerKey));
SG_LOG(SG_INPUT, SG_INFO, "removed device:" << productName << " from " << manufacturer);
// see if we have an entry for the device // see if we have an entry for the device
} }
@ -327,21 +338,16 @@ FGMacOSXInputDevice::FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
FGMacOSXInputDevice::~FGMacOSXInputDevice() FGMacOSXInputDevice::~FGMacOSXInputDevice()
{ {
NameElementDict::iterator it;
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
CFRelease(it->second);
}
CFRelease(_queue); CFRelease(_queue);
CFRelease(_hid); CFRelease(_hid);
} }
void FGMacOSXInputDevice::Open() void FGMacOSXInputDevice::Open()
{ {
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone); IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this); // IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
@ -431,8 +437,11 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
namedElements[os.str()] = namedElements[name]; namedElements[os.str()] = namedElements[name];
CFRetain(namedElements[os.str()]); CFRetain(namedElements[os.str()]);
} }
} }
#if 1
// HID debugging code
#if 0
NameElementDict::const_iterator it; NameElementDict::const_iterator it;
for (it = namedElements.begin(); it != namedElements.end(); ++it) { for (it = namedElements.begin(); it != namedElements.end(); ++it) {
int report = IOHIDElementGetReportID(it->second); int report = IOHIDElementGetReportID(it->second);
@ -457,15 +466,25 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
void FGMacOSXInputDevice::Close() void FGMacOSXInputDevice::Close()
{ {
// leaking these otherwise we get a crash shutting down the HID-manager
// object. Don't understand why that should be the case
#if 0
for (auto it : namedElements) {
CFRelease(it.second);
}
#endif
namedElements.clear();
IOHIDQueueStop(_queue); IOHIDQueueStop(_queue);
IOHIDQueueUnscheduleFromRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone); IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
} }
void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent ) void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
{ {
SG_LOG(SG_INPUT, SG_INFO, "adding event:" << handledEvent->GetName()); SG_LOG(SG_INPUT, SG_DEBUG, "adding event:" << handledEvent->GetName());
if (namedElements.empty()) { if (namedElements.empty()) {
buildElementNameDictionary(); buildElementNameDictionary();
} }
@ -476,6 +495,7 @@ void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
return; return;
} }
IOHIDQueueAddElement(_queue, it->second); IOHIDQueueAddElement(_queue, it->second);
FGInputDevice::AddHandledEvent(handledEvent); FGInputDevice::AddHandledEvent(handledEvent);
} }