Skip to content

Commit

Permalink
testSafeToExecute*: fix threading issues (#1455)
Browse files Browse the repository at this point in the history
Motivation:

testSafeToExecuteTrue/False accessed an internal property of the event
loop without synchronisation.

Modifications:

Fix the threading issue.

Result:

Tests with TSan happy.
  • Loading branch information
weissi authored Mar 18, 2020
1 parent bd4df32 commit a27a077
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
12 changes: 9 additions & 3 deletions Sources/NIO/SelectableEventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ internal final class SelectableEventLoop: EventLoop {
}
}

@usableFromInline
internal var _validExternalStateToScheduleTasks: Bool {
// access with `externalStateLock` held
private var validExternalStateToScheduleTasks: Bool {
switch self.externalState {
case .open, .closing:
return true
Expand All @@ -125,6 +125,12 @@ internal final class SelectableEventLoop: EventLoop {
}
}

internal var testsOnly_validExternalStateToScheduleTasks: Bool {
return self.externalStateLock.withLock {
return self.validExternalStateToScheduleTasks
}
}

internal init(thread: NIOThread, selector: NIO.Selector<NIORegistration>) {
self._selector = selector
self.thread = thread
Expand Down Expand Up @@ -261,7 +267,7 @@ internal final class SelectableEventLoop: EventLoop {
}
} else {
self.externalStateLock.withLockVoid {
guard self._validExternalStateToScheduleTasks else {
guard self.validExternalStateToScheduleTasks else {
print("ERROR: Cannot schedule tasks on an EventLoop that has already shut down. " +
"This will be upgraded to a forced crash in future SwiftNIO versions.")
return
Expand Down
8 changes: 4 additions & 4 deletions Tests/NIOTests/EventLoopTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1074,15 +1074,15 @@ public final class EventLoopTest : XCTestCase {
XCTAssertNoThrow(try elg.syncShutdownGracefully())
}
let loop = elg.next() as! SelectableEventLoop
XCTAssertTrue(loop._validInternalStateToScheduleTasks)
XCTAssertTrue(loop._validExternalStateToScheduleTasks)
XCTAssertTrue(loop.testsOnly_validExternalStateToScheduleTasks)
XCTAssertTrue(loop.testsOnly_validExternalStateToScheduleTasks)
}

func testSafeToExecuteFalse() {
let elg = MultiThreadedEventLoopGroup(numberOfThreads: 1)
let loop = elg.next() as! SelectableEventLoop
try? elg.syncShutdownGracefully()
XCTAssertFalse(loop._validInternalStateToScheduleTasks)
XCTAssertFalse(loop._validExternalStateToScheduleTasks)
XCTAssertFalse(loop.testsOnly_validExternalStateToScheduleTasks)
XCTAssertFalse(loop.testsOnly_validExternalStateToScheduleTasks)
}
}

0 comments on commit a27a077

Please sign in to comment.