Permalink
Browse files

Expand a lock in the connection keepalive code, because it still allo…

…wed a zombie call
  • Loading branch information...
dmoagx committed May 11, 2017
1 parent 23c4d04 commit f741be75bc3f3d0964942a66d0fafc7ba0c62208
Showing with 19 additions and 2 deletions.
  1. +19 −2 Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Ping & KeepAlive.m
@@ -85,9 +85,9 @@ - (void)_threadedKeepAlive
if(keepAliveThread) {
NSLog(@"warning: overwriting existing keepAliveThread: %@, results may be unpredictable!",keepAliveThread);
}
keepAliveThread = [NSThread currentThread];
}
keepAliveThread = [NSThread currentThread];
[keepAliveThread setName:[NSString stringWithFormat:@"SPMySQL connection keepalive monitor thread (id=%p)", self]];
// If the maximum number of ping failures has been reached, determine whether to reconnect.
@@ -282,7 +282,24 @@ - (BOOL)_cancelKeepAlives
if (keepAliveThread) {
// Mark the thread as cancelled
[keepAliveThread cancel];
@synchronized(self) {
// the synchronized is neccesary here, because we don't retain keepAliveThread.
// If it were ommitted, for example this could happen:
//
// this thread keepalive thread
// -------------- -----------------
// 1 fetch value of keepAliveThread to register
// 2 keepAliveThread = nil
// 3 [[NSThread currentThread] release]
// 4 objc_msgSend() <-- invalid memory accessed
//
// With synchronized we are guaranteed to either message nil or block the keepAliveThread from exiting
// (and thus releasing the NSThread object) until this call finishes.
//
// We can omit it in the other 2 cases, since keepAliveThread is already volatile and we are only
// checking for NULL, not dereferencing it.
[keepAliveThread cancel];
}
// Wait inside a time limit of ten seconds for it to exit
uint64_t threadCancelStartTime_t = mach_absolute_time();

0 comments on commit f741be7

Please sign in to comment.