Skip to content

Commit 65dbe53

Browse files
committed
Custom execution context
1 parent d14be3a commit 65dbe53

File tree

5 files changed

+122
-20
lines changed

5 files changed

+122
-20
lines changed

ExecutionContext.xcodeproj/project.pbxproj

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
659E80DD1C78A4F000DE85B1 /* ExecutionContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 659E808D1C77450200DE85B1 /* ExecutionContextTests.swift */; };
2626
659E81121C78A71F00DE85B1 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 659E80E31C78A70700DE85B1 /* Result.framework */; };
2727
659E81131C78A72C00DE85B1 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 659E80E61C78A70700DE85B1 /* Result.framework */; };
28+
65E646DD1C79949C0036D028 /* CustomExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */; };
29+
65E646DE1C7994A00036D028 /* CustomExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */; };
30+
65E646DF1C7994A10036D028 /* CustomExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */; };
31+
65E646E01C7994A20036D028 /* CustomExecutionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */; };
2832
65FB86901C78A8330005CD1B /* Result.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 659E80E61C78A70700DE85B1 /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2933
65FB86921C78A8D30005CD1B /* Result.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 659E80E31C78A70700DE85B1 /* Result.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
3034
65FB86A21C78AA400005CD1B /* ExecutionContext.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65FB86981C78AA400005CD1B /* ExecutionContext.framework */; };
@@ -136,6 +140,7 @@
136140
659E80EF1C78A70700DE85B1 /* B2361319-6010-3366-BA4B-B28167D21368.bcsymbolmap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "B2361319-6010-3366-BA4B-B28167D21368.bcsymbolmap"; sourceTree = "<group>"; };
137141
659E80F01C78A70700DE85B1 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = "<group>"; };
138142
659E80F11C78A70700DE85B1 /* Result.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; path = Result.framework.dSYM; sourceTree = "<group>"; };
143+
65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomExecutionContext.swift; sourceTree = "<group>"; };
139144
65FB86981C78AA400005CD1B /* ExecutionContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExecutionContext.framework; sourceTree = BUILT_PRODUCTS_DIR; };
140145
65FB86A11C78AA400005CD1B /* ExecutionContextTests-tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ExecutionContextTests-tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
141146
65FB86BE1C78AC260005CD1B /* ExecutionContext.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ExecutionContext.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -233,6 +238,7 @@
233238
659E80991C77457E00DE85B1 /* DispatchExecutionContext.swift */,
234239
659E809C1C77457E00DE85B1 /* PThreadExecutionContext.swift */,
235240
659E809B1C77457E00DE85B1 /* ImmediateExecutionContext.swift */,
241+
65E646DC1C79949C0036D028 /* CustomExecutionContext.swift */,
236242
659E809D1C77457E00DE85B1 /* Result+Some.swift */,
237243
659E80831C77450200DE85B1 /* Info.plist */,
238244
);
@@ -586,6 +592,7 @@
586592
files = (
587593
659E809F1C77457E00DE85B1 /* DispatchExecutionContext.swift in Sources */,
588594
659E80A01C77457E00DE85B1 /* ExecutionContext.swift in Sources */,
595+
65E646DD1C79949C0036D028 /* CustomExecutionContext.swift in Sources */,
589596
659E80A31C77457E00DE85B1 /* Result+Some.swift in Sources */,
590597
659E80A11C77457E00DE85B1 /* ImmediateExecutionContext.swift in Sources */,
591598
659E809E1C77457E00DE85B1 /* DefaultExecutionContext.swift in Sources */,
@@ -607,6 +614,7 @@
607614
files = (
608615
659E80D81C78A4AF00DE85B1 /* DefaultExecutionContext.swift in Sources */,
609616
659E80DA1C78A4B500DE85B1 /* PThreadExecutionContext.swift in Sources */,
617+
65E646DE1C7994A00036D028 /* CustomExecutionContext.swift in Sources */,
610618
659E80DC1C78A4BC00DE85B1 /* Result+Some.swift in Sources */,
611619
659E80DB1C78A4B800DE85B1 /* ImmediateExecutionContext.swift in Sources */,
612620
659E80D71C78A4AB00DE85B1 /* ExecutionContext.swift in Sources */,
@@ -628,6 +636,7 @@
628636
files = (
629637
65FB86B01C78AAE00005CD1B /* DefaultExecutionContext.swift in Sources */,
630638
65FB86B21C78AAE50005CD1B /* PThreadExecutionContext.swift in Sources */,
639+
65E646DF1C7994A10036D028 /* CustomExecutionContext.swift in Sources */,
631640
65FB86B41C78AAE50005CD1B /* Result+Some.swift in Sources */,
632641
65FB86B31C78AAE50005CD1B /* ImmediateExecutionContext.swift in Sources */,
633642
65FB86AF1C78AADB0005CD1B /* ExecutionContext.swift in Sources */,
@@ -649,6 +658,7 @@
649658
files = (
650659
65FB86C71C78AC8B0005CD1B /* DefaultExecutionContext.swift in Sources */,
651660
65FB86C91C78AC8B0005CD1B /* PThreadExecutionContext.swift in Sources */,
661+
65E646E01C7994A20036D028 /* CustomExecutionContext.swift in Sources */,
652662
65FB86CB1C78AC8B0005CD1B /* Result+Some.swift in Sources */,
653663
65FB86CA1C78AC8B0005CD1B /* ImmediateExecutionContext.swift in Sources */,
654664
65FB86C61C78AC8B0005CD1B /* ExecutionContext.swift in Sources */,
@@ -1104,6 +1114,7 @@
11041114
65FB86AB1C78AA400005CD1B /* Release */,
11051115
);
11061116
defaultConfigurationIsVisible = 0;
1117+
defaultConfigurationName = Release;
11071118
};
11081119
65FB86AC1C78AA400005CD1B /* Build configuration list for PBXNativeTarget "ExecutionContextTests-tvOS" */ = {
11091120
isa = XCConfigurationList;
@@ -1112,6 +1123,7 @@
11121123
65FB86AE1C78AA400005CD1B /* Release */,
11131124
);
11141125
defaultConfigurationIsVisible = 0;
1126+
defaultConfigurationName = Release;
11151127
};
11161128
65FB86C31C78AC260005CD1B /* Build configuration list for PBXNativeTarget "ExecutionContext-watchOS" */ = {
11171129
isa = XCConfigurationList;
@@ -1120,6 +1132,7 @@
11201132
65FB86C51C78AC260005CD1B /* Release */,
11211133
);
11221134
defaultConfigurationIsVisible = 0;
1135+
defaultConfigurationName = Release;
11231136
};
11241137
/* End XCConfigurationList section */
11251138
};
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===--- CustomExecutionContext.swift ------------------------------------------------------===//
2+
//Copyright (c) 2016 Daniel Leping (dileping)
3+
//
4+
//Licensed under the Apache License, Version 2.0 (the "License");
5+
//you may not use this file except in compliance with the License.
6+
//You may obtain a copy of the License at
7+
//
8+
//http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
//Unless required by applicable law or agreed to in writing, software
11+
//distributed under the License is distributed on an "AS IS" BASIS,
12+
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
//See the License for the specific language governing permissions and
14+
//limitations under the License.
15+
//===----------------------------------------------------------------------===//
16+
17+
import Foundation
18+
19+
public class CustomExecutionContext : ExecutionContextBase, ExecutionContextType {
20+
let executor:Executor
21+
22+
public init(executor:Executor) {
23+
self.executor = executor
24+
}
25+
26+
public func async(task:SafeTask) {
27+
executor(task)
28+
}
29+
30+
public func async(after:Double, task:SafeTask) {
31+
let sec = time_t(after)
32+
let nsec = Int((after - Double(sec)) * 1000 * 1000 * 1000)//nano seconds
33+
var time = timespec(tv_sec:sec, tv_nsec: nsec)
34+
35+
async {
36+
nanosleep(&time, nil)
37+
task()
38+
}
39+
}
40+
41+
public func sync<ReturnType>(task:() throws -> ReturnType) throws -> ReturnType {
42+
return try syncThroughAsync(task)
43+
}
44+
}

ExecutionContext/ExecutionContext.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
import Foundation
18+
import Result
1819

1920
public typealias Task = () throws -> Void
2021
public typealias SafeTask = () -> Void
@@ -124,6 +125,37 @@ public enum ExecutionContextKind {
124125

125126
public typealias ExecutionContext = DefaultExecutionContext
126127

128+
extension ExecutionContextType {
129+
func syncThroughAsync<ReturnType>(task:() throws -> ReturnType) throws -> ReturnType {
130+
var result:Result<ReturnType, AnyError>?
131+
132+
let cond = NSCondition()
133+
var done = false
134+
135+
async {
136+
defer {
137+
cond.lock()
138+
done = true
139+
cond.signal()
140+
cond.unlock()
141+
}
142+
result = materialize(task)
143+
}
144+
145+
cond.lock()
146+
while !done {
147+
cond.wait()
148+
}
149+
cond.unlock()
150+
151+
return try result!.dematerializeAnyError()
152+
}
153+
}
154+
127155
public let immediate:ExecutionContextType = ImmediateExecutionContext()
128156
public let main:ExecutionContextType = ExecutionContext.main
129157
public let global:ExecutionContextType = ExecutionContext.global
158+
159+
public func executionContext(executor:Executor) -> ExecutionContextType {
160+
return CustomExecutionContext(executor: executor)
161+
}

ExecutionContext/PThreadExecutionContext.swift

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,6 @@
188188
}
189189
}
190190

191-
private extension ExecutionContextType {
192-
func syncThroughAsync<ReturnType>(task:() throws -> ReturnType) throws -> ReturnType {
193-
var result:Result<ReturnType, AnyError>?
194-
195-
let cond = NSCondition()
196-
cond.lock()
197-
198-
async {
199-
result = materialize(task)
200-
cond.signal()
201-
}
202-
203-
cond.wait()
204-
cond.unlock()
205-
206-
return try result!.dematerializeAnyError()
207-
}
208-
}
209-
210191
private class ParallelContext : ExecutionContextBase, ExecutionContextType {
211192
func async(task:SafeTask) {
212193
let thread = PThread(task: task)

Tests/ExecutionContext/ExecutionContextTests.swift

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,35 @@ class ExecutionContextTests: XCTestCase {
105105
afterTest(context)
106106
//afterTestAdvanced - no it will not work here
107107
}
108+
109+
func testCustomOnGlobal() {
110+
let context = executionContext(global.execute)
111+
112+
syncTest(context)
113+
asyncTest(context)
114+
afterTest(context)
115+
afterTestAdvanced(context)
116+
}
117+
118+
func testCustomOnMain() {
119+
let context = executionContext(global.execute)
120+
121+
syncTest(context)
122+
asyncTest(context)
123+
afterTest(context)
124+
//afterTestAdvanced - no it will not work here
125+
}
126+
127+
func testCustomSimple() {
128+
let context = executionContext { task in
129+
task()
130+
}
131+
132+
syncTest(context)
133+
asyncTest(context)
134+
afterTest(context)
135+
//afterTestAdvanced - no it will not work here
136+
}
108137
}
109138

110139
#if os(Linux)
@@ -114,7 +143,10 @@ extension ExecutionContextTests : XCTestCaseProvider {
114143
("testSerial", testSerial),
115144
("testParallel", testParallel),
116145
("testGlobal", testGlobal),
117-
("testMain", testMain)
146+
("testMain", testMain),
147+
("testMain", testCustomOnGlobal),
148+
("testMain", testCustomOnMain),
149+
("testMain", testCustomSimple)
118150
]
119151
}
120152
}

0 commit comments

Comments
 (0)