8000 Fix crash when restarting OSX single shot timer by dopplershift · Pull Request #9662 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 36 additions & 55 deletions src/_macosx.m
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
[pool release];
}

Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -362,8 +361,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
return NULL;
}
[view setNeedsDisplay: YES];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -376,8 +374,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
return NULL;
}
[view displayIfNeeded];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand Down Expand Up @@ -420,8 +417,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
}

[view setRubberband: rubberband];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -434,8 +430,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
return NULL;
}
[view removeRubberband];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static NSImage* _read_ppm_image(PyObject* obj)
Expand Down Expand Up @@ -546,8 +541,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
if (error==0) close(channel[1]);
if (interrupted) raise(SIGINT);

Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -563,8 +557,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
data1: 0
data2: 0];
[NSApp postEvent: event atStart: true];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyMethodDef FigureCanvas_methods[] = {
Expand Down Expand Up @@ -770,8 +763,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
[window orderFrontRegardless];
[pool release];
}
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -785,8 +777,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
[pool release];
self->window = NULL;
}
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -808,8 +799,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
[pool release];
}
PyMem_Free(title);
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -830,8 +820,7 @@ static CGFloat _get_device_scale(CGContextRef cr)
if (result) {
return result;
} else {
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}
}

Expand Down Expand Up @@ -1280,8 +1269,7 @@ -(void)save_figure:(id)sender
[button setEnabled: YES];
}
[pool release];
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand Down Expand Up @@ -1783,8 +1771,7 @@ -(void)save_figure:(id)sender
[pool release];
}

Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyMethodDef NavigationToolbar2_methods[] = {
Expand Down Expand Up @@ -1888,8 +1875,7 @@ -(void)save_figure:(id)sender
free(buffer);
return string;
}
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Expand All @@ -1906,8 +1892,7 @@ -(void)save_figure:(id)sender
case 4: break;
default: return NULL;
}
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

@implementation WindowServerConnectionManager
Expand Down Expand Up @@ -2845,8 +2830,7 @@ - (int)index
Py_BEGIN_ALLOW_THREADS
[NSApp run];
Py_END_ALLOW_THREADS
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

typedef struct {
Expand Down Expand Up @@ -2883,10 +2867,19 @@ static void timer_callback(CFRunLoopTimerRef timer, void* info)
PyObject* method = info;
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* result = PyObject_CallFunction(method, NULL);
if (result==NULL) PyErr_Print();
if (result) {
Py_DECREF(result);
} else {
PyErr_Print();
}
PyGILState_Release(gstate);
}

static void context_cleanup(const void* info)
{
Py_DECREF((PyObject*)info);
}

static PyObject*
Timer__timer_start(Timer* self, PyObject* args)
{
Expand All @@ -2902,10 +2895,6 @@ static void timer_callback(CFRunLoopTimerRef timer, void* info)
PyErr_SetString(PyExc_RuntimeError, "Failed to obtain run loop");
return NULL;
}
context.version = 0;
context.retain = 0;
context.release = 0;
context.copyDescription = 0;
attribute = PyObject_GetAttrString((PyObject*)self, "_interval");
if (attribute==NULL)
{
Expand Down Expand Up @@ -2934,6 +2923,7 @@ static void timer_callback(CFRunLoopTimerRef timer, void* info)
PyErr_SetString(PyExc_ValueError, "Cannot interpret _single attribute as True of False");
return NULL;
}
Py_DECREF(attribute);
attribute = PyObject_GetAttrString((PyObject*)self, "_on_timer");
if (attribute==NULL)
{
Expand All @@ -2944,6 +2934,10 @@ static void timer_callback(CFRunLoopTimerRef timer, void* info)
PyErr_SetString(PyExc_RuntimeError, "_on_timer should be a Python method");
return NULL;
}
context.version = 0;
context.retain = NULL;
context.release = context_cleanup;
context.copyDescription = NULL;
context.info = attribute;
timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
0,
Expand All @@ -2953,44 +2947,31 @@ static void timer_callback(CFRunLoopTimerRef timer, void* info)
timer_callback,
&context);
if (!timer) {
Py_DECREF(attribute);
PyErr_SetString(PyExc_RuntimeError, "Failed to create timer");
return NULL;
}
Py_INCREF(attribute);
if (self->timer) {
CFRunLoopTimerGetContext(self->timer, &context);
attribute = context.info;
Py_DECREF(attribute);
CFRunLoopRemoveTimer(runloop, self->timer, kCFRunLoopCommonModes);
CFRunLoopTimerInvalidate(self->timer);
CFRelease(self->timer);
}
CFRunLoopAddTimer(runloop, timer, kCFRunLoopCommonModes);
/* Don't release the timer here, since the run loop may be destroyed and
* the timer lost before we have a chance to decrease the reference count
* of the attribute */
self->timer = timer;
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static PyObject*
Timer__timer_stop(Timer* self)
{
if (self->timer) {
PyObject* attribute;
CFRunLoopTimerContext context;
CFRunLoopTimerGetContext(self->timer, &context);
attribute = context.info;
Py_DECREF(attribute);
CFRunLoopRef runloop = CFRunLoopGetCurrent();
if (runloop) {
CFRunLoopRemoveTimer(runloop, self->timer, kCFRunLoopCommonModes);
}
CFRunLoopTimerInvalidate(self->timer);
CFRelease(self->timer);
self->timer = NULL;
}
Py_INCREF(Py_None);
return Py_None;
Py_RETURN_NONE;
}

static void
Expand Down
0