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

View file

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

View file

@ -153,8 +153,8 @@ public:
virtual ~FGMacOSXInputDevice();
void Open();
void Close();
void Open() override;
void Close() override;
virtual void update(double dt);
virtual const char *TranslateEventName(FGEventData &eventData);
@ -169,7 +169,7 @@ private:
void buildElementNameDictionary();
std::string nameForHIDElement(IOHIDElementRef element) const;
IOHIDDeviceRef _hid;
IOHIDQueueRef _queue;
FGMacOSXEventInputPrivate* _subsystem;
@ -227,6 +227,11 @@ void FGMacOSXEventInput::postinit()
void FGMacOSXEventInput::shutdown()
{
FGEventInput::shutdown();
IOHIDManagerRegisterDeviceMatchingCallback(d->hidManager, nullptr, nullptr);
IOHIDManagerRegisterDeviceRemovalCallback(d->hidManager, nullptr, nullptr);
IOHIDManagerClose(d->hidManager, kIOHIDOptionsTypeNone);
IOHIDManagerUnscheduleFromRunLoop(d->hidManager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
CFRelease(d->hidManager);
@ -259,6 +264,12 @@ void FGMacOSXEventInputPrivate::matchedDevice(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
}
@ -327,21 +338,16 @@ FGMacOSXInputDevice::FGMacOSXInputDevice(IOHIDDeviceRef hidRef,
FGMacOSXInputDevice::~FGMacOSXInputDevice()
{
NameElementDict::iterator it;
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
CFRelease(it->second);
}
CFRelease(_queue);
CFRelease(_hid);
}
void FGMacOSXInputDevice::Open()
{
IOHIDDeviceOpen(_hid, kIOHIDOptionsTypeNone);
IOHIDDeviceScheduleWithRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
// IOHIDQueueRegisterValueAvailableCallback(_queue, valueAvailableCallback, this);
IOHIDQueueScheduleWithRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
@ -431,8 +437,11 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
namedElements[os.str()] = namedElements[name];
CFRetain(namedElements[os.str()]);
}
}
#if 1
// HID debugging code
#if 0
NameElementDict::const_iterator it;
for (it = namedElements.begin(); it != namedElements.end(); ++it) {
int report = IOHIDElementGetReportID(it->second);
@ -457,15 +466,25 @@ void FGMacOSXInputDevice::buildElementNameDictionary()
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);
IOHIDQueueUnscheduleFromRunLoop(_queue, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDDeviceUnscheduleFromRunLoop(_hid, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
IOHIDDeviceClose(_hid, kIOHIDOptionsTypeNone);
}
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()) {
buildElementNameDictionary();
}
@ -476,6 +495,7 @@ void FGMacOSXInputDevice::AddHandledEvent( FGInputEvent_ptr handledEvent )
return;
}
IOHIDQueueAddElement(_queue, it->second);
FGInputDevice::AddHandledEvent(handledEvent);
}