Skip to content

Commit 6205e83

Browse files
committed
Fix destroy race conditions
1 parent ce46b7a commit 6205e83

2 files changed

Lines changed: 27 additions & 12 deletions

File tree

src/window-osx.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <map>
3131
#include <iostream>
3232
#include <thread>
33+
#include <mutex>
3334

3435
@interface WindowImplObj : NSObject
3536
@end
@@ -42,16 +43,18 @@ struct OpenGLData {
4243
GLuint mPosAttribute;
4344
GLuint mVertexbuffer;
4445
IOSurfaceRef surface = NULL;
46+
std::thread* thread;
47+
std::mutex mtx;
48+
bool stop = false;
4549
};
4650

4751
@interface OpenGLView: NSView
4852
@property (atomic) OpenGLData* glData;
4953
@end
5054

5155
struct WindowInfo {
52-
bool stop = false;
53-
std::thread* thread;
5456
OpenGLView* view;
57+
bool destroyed = false;
5558
};
5659

5760
std::map<void*, void*> windows; // <NSView* parent, WindowInfo* wi>

src/window-osx.mm

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020

2121
void renderFrames(WindowInfo* wi)
2222
{
23-
while (!wi->stop) {
23+
while (!wi->view.glData->stop) {
2424
std::this_thread::sleep_for(std::chrono::milliseconds(16));
25-
dispatch_sync(dispatch_get_main_queue(), ^{
26-
if (!wi->stop) {
25+
26+
dispatch_async(dispatch_get_main_queue(), ^{
27+
if (!wi->destroyed && !wi->view.glData->stop) {
2728
wi->view.needsDisplay = YES;
2829
}
2930
});
@@ -120,9 +121,6 @@ - (id)initWithFrame:(NSRect)aFrame
120121

121122
- (void)dealloc
122123
{
123-
[self _cleanupGL];
124-
[NSOpenGLContext clearCurrentContext];
125-
[self.glData->mContext release];
126124
[super dealloc];
127125
}
128126

@@ -275,9 +273,11 @@ - (void)_surfaceNeedsUpdate:(NSNotification*)notification
275273

276274
- (void)drawRect:(NSRect)aRect
277275
{
278-
if (!self.glData->surface)
276+
if (!self.glData->surface || self.glData->stop)
279277
return;
280278

279+
self.glData->mtx.lock();
280+
281281
CGLTexImageIOSurface2D([self.glData->mContext CGLContextObj],
282282
GL_TEXTURE_RECTANGLE_ARB, GL_RGBA,
283283
IOSurfaceGetWidth(self.glData->surface),
@@ -341,6 +341,7 @@ - (void)drawRect:(NSRect)aRect
341341
gl_success("glDisableVertexAttribArray");
342342

343343
[self.glData->mContext flushBuffer];
344+
self.glData->mtx.unlock();
344345
}
345346

346347
- (BOOL)wantsBestResolutionOpenGLSurface
@@ -398,7 +399,18 @@ @implementation WindowImplObj
398399
return;
399400

400401
WindowInfo* wi = reinterpret_cast<WindowInfo*>(it->second);
401-
wi->stop = true;
402+
wi->view.glData->mtx.lock();
403+
wi->view.glData->stop = true;
404+
405+
if (wi->view.glData->thread->joinable())
406+
wi->view.glData->thread->join();
407+
408+
[self _cleanupGL];
409+
[NSOpenGLContext clearCurrentContext];
410+
[wi->view.glData->mContext release];
411+
wi->destroyed = true;
412+
wi->view.glData->mtx.unlock();
413+
402414
[wi->view removeFromSuperview];
403415
CFRelease(wi->view);
404416

@@ -418,8 +430,8 @@ @implementation WindowImplObj
418430
if (!wi->view.glData->surface)
419431
return;
420432

421-
wi->stop = false;
422-
wi->thread = new std::thread(renderFrames, wi);
433+
wi->view.glData->stop = false;
434+
wi->view.glData->thread = new std::thread(renderFrames, wi);
423435

424436
[wi->view setFrameSize:NSMakeSize(IOSurfaceGetWidth(wi->view.glData->surface),
425437
IOSurfaceGetHeight(wi->view.glData->surface))];

0 commit comments

Comments
 (0)