Skip to content

Commit 11df58b

Browse files
committed
Merge branch 'build-android-script' of http://github.com/amraboelela/swift-corelibs-foundation into build-android-script
2 parents a62b113 + 0d6e98d commit 11df58b

File tree

13 files changed

+413
-116
lines changed

13 files changed

+413
-116
lines changed

Docs/Status.md

Lines changed: 19 additions & 19 deletions
Large diffs are not rendered by default.

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@
326326
B910957B1EEF237800A71930 /* NSString-UTF16-BE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */; };
327327
B933A79E1F3055F700FE6846 /* NSString-UTF32-BE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */; };
328328
B933A79F1F3055F700FE6846 /* NSString-UTF32-LE-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = B933A79D1F3055F600FE6846 /* NSString-UTF32-LE-data.txt */; };
329+
B951B5EC1F4E2A2000D8B332 /* TestNSLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */; };
329330
B9974B961EDF4A22007F15B8 /* TransferState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B8F1EDF4A22007F15B8 /* TransferState.swift */; };
330331
B9974B971EDF4A22007F15B8 /* MultiHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B901EDF4A22007F15B8 /* MultiHandle.swift */; };
331332
B9974B981EDF4A22007F15B8 /* libcurlHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9974B911EDF4A22007F15B8 /* libcurlHelpers.swift */; };
@@ -795,6 +796,7 @@
795796
B91095791EEF237800A71930 /* NSString-UTF16-BE-data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "NSString-UTF16-BE-data.txt"; sourceTree = "<group>"; };
796797
B933A79C1F3055F600FE6846 /* NSString-UTF32-BE-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NSString-UTF32-BE-data.txt"; sourceTree = "<group>"; };
797798
B933A79D1F3055F600FE6846 /* NSString-UTF32-LE-data.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "NSString-UTF32-LE-data.txt"; sourceTree = "<group>"; };
799+
B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestNSLock.swift; sourceTree = "<group>"; };
798800
B9974B8F1EDF4A22007F15B8 /* TransferState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TransferState.swift; path = http/TransferState.swift; sourceTree = "<group>"; };
799801
B9974B901EDF4A22007F15B8 /* MultiHandle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MultiHandle.swift; path = http/MultiHandle.swift; sourceTree = "<group>"; };
800802
B9974B911EDF4A22007F15B8 /* libcurlHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = libcurlHelpers.swift; path = http/libcurlHelpers.swift; sourceTree = "<group>"; };
@@ -1498,6 +1500,7 @@
14981500
400E22641C1A4E58007C5933 /* TestProcessInfo.swift */,
14991501
EA01AAEB1DA839C4008F4E07 /* TestProgress.swift */,
15001502
5E5835F31C20C9B500C81317 /* TestThread.swift */,
1503+
B951B5EB1F4E2A2000D8B332 /* TestNSLock.swift */,
15011504
CC5249BF1D341D23007CB54D /* TestUnitConverter.swift */,
15021505
D4FE895A1D703D1100DA7986 /* TestURLRequest.swift */,
15031506
5B6F17961C48631C00935030 /* TestUtils.swift */,
@@ -2445,6 +2448,7 @@
24452448
D512D17C1CD883F00032E6A5 /* TestFileHandle.swift in Sources */,
24462449
D4FE895B1D703D1100DA7986 /* TestURLRequest.swift in Sources */,
24472450
684C79011F62B611005BD73E /* TestNSNumberBridging.swift in Sources */,
2451+
B951B5EC1F4E2A2000D8B332 /* TestNSLock.swift in Sources */,
24482452
5B13B33A1C582D4C00651CE2 /* TestNSNumber.swift in Sources */,
24492453
5B13B3521C582D4C00651CE2 /* TestNSValue.swift in Sources */,
24502454
5B13B3311C582D4C00651CE2 /* TestIndexPath.swift in Sources */,

Foundation/NSDictionary.swift

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ open class NSDictionary : NSObject, NSCopying, NSMutableCopying, NSSecureCoding,
4444
return NSGeneratorEnumerator(_storage.keys.map { _SwiftValue.fetch(nonOptional: $0) }.makeIterator())
4545
}
4646

47+
@available(*, deprecated)
48+
public convenience init?(contentsOfFile path: String) {
49+
self.init(contentsOf: URL(fileURLWithPath: path))
50+
}
51+
52+
@available(*, deprecated)
53+
public convenience init?(contentsOf url: URL) {
54+
do {
55+
guard let plistDoc = try? Data(contentsOf: url) else { return nil }
56+
let plistDict = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Dictionary<AnyHashable,Any>
57+
guard let plistDictionary = plistDict else { return nil }
58+
self.init(dictionary: plistDictionary)
59+
} catch {
60+
return nil
61+
}
62+
}
63+
4764
public override convenience init() {
4865
self.init(objects: [], forKeys: [], count: 0)
4966
}
@@ -587,20 +604,6 @@ open class NSMutableDictionary : NSDictionary {
587604
super.init(objects: objects, forKeys: keys, count: cnt)
588605
}
589606

590-
public convenience init?(contentsOfFile path: String) {
591-
self.init(contentsOfURL: URL(fileURLWithPath: path))
592-
}
593-
594-
public convenience init?(contentsOfURL url: URL) {
595-
do {
596-
guard let plistDoc = try? Data(contentsOf: url) else { return nil }
597-
let plistDict = try PropertyListSerialization.propertyList(from: plistDoc, options: [], format: nil) as? Dictionary<AnyHashable,Any>
598-
guard let plistDictionary = plistDict else { return nil }
599-
self.init(dictionary: plistDictionary)
600-
} catch {
601-
return nil
602-
}
603-
}
604607
}
605608

606609
extension NSMutableDictionary {

Foundation/NSLock.swift

Lines changed: 130 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// This source file is part of the Swift.org open source project
22
//
3-
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
3+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
44
// Licensed under Apache License v2.0 with Runtime Library Exception
55
//
66
// See http://swift.org/LICENSE.txt for license information
@@ -21,39 +21,71 @@ public protocol NSLocking {
2121
func unlock()
2222
}
2323

24-
open class NSLock: NSObject, NSLocking {
2524
#if CYGWIN
26-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
25+
private typealias _PthreadMutexPointer = UnsafeMutablePointer<pthread_mutex_t?>
26+
private typealias _PthreadCondPointer = UnsafeMutablePointer<pthread_cond_t?>
2727
#else
28-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
28+
private typealias _PthreadMutexPointer = UnsafeMutablePointer<pthread_mutex_t>
29+
private typealias _PthreadCondPointer = UnsafeMutablePointer<pthread_cond_t>
2930
#endif
30-
31+
32+
open class NSLock: NSObject, NSLocking {
33+
internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
34+
#if os(OSX) || os(iOS)
35+
private var timeoutCond = _PthreadCondPointer.allocate(capacity: 1)
36+
private var timeoutMutex = _PthreadMutexPointer.allocate(capacity: 1)
37+
#endif
38+
3139
public override init() {
3240
pthread_mutex_init(mutex, nil)
41+
#if os(OSX) || os(iOS)
42+
pthread_cond_init(timeoutCond, nil)
43+
pthread_mutex_init(timeoutMutex, nil)
44+
#endif
3345
}
3446

3547
deinit {
3648
pthread_mutex_destroy(mutex)
3749
mutex.deinitialize()
3850
mutex.deallocate(capacity: 1)
51+
#if os(OSX) || os(iOS)
52+
deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
53+
#endif
3954
}
4055

4156
open func lock() {
4257
pthread_mutex_lock(mutex)
4358
}
44-
59+
4560
open func unlock() {
4661
pthread_mutex_unlock(mutex)
62+
#if os(OSX) || os(iOS)
63+
// Wakeup any threads waiting in lock(before:)
64+
pthread_mutex_lock(timeoutMutex)
65+
pthread_cond_broadcast(timeoutCond)
66+
pthread_mutex_unlock(timeoutMutex)
67+
#endif
4768
}
48-
69+
4970
open func `try`() -> Bool {
5071
return pthread_mutex_trylock(mutex) == 0
5172
}
5273

53-
open func lock(before limit: Date) {
54-
NSUnimplemented()
74+
open func lock(before limit: Date) -> Bool {
75+
if pthread_mutex_trylock(mutex) == 0 {
76+
return true
77+
}
78+
79+
#if os(OSX) || os(iOS)
80+
return timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
81+
#else
82+
guard var endTime = timeSpecFrom(date: limit) else {
83+
return false
84+
}
85+
return pthread_mutex_timedlock(mutex, &endTime) == 0
86+
#endif
5587
}
56-
88+
5789
open var name: String?
5890
}
5991

@@ -143,12 +175,12 @@ open class NSConditionLock : NSObject, NSLocking {
143175
}
144176

145177
open class NSRecursiveLock: NSObject, NSLocking {
146-
#if CYGWIN
147-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
148-
#else
149-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
178+
internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
179+
#if os(OSX) || os(iOS)
180+
private var timeoutCond = _PthreadCondPointer.allocate(capacity: 1)
181+
private var timeoutMutex = _PthreadMutexPointer.allocate(capacity: 1)
150182
#endif
151-
183+
152184
public override init() {
153185
super.init()
154186
#if CYGWIN
@@ -166,6 +198,9 @@ open class NSRecursiveLock: NSObject, NSLocking {
166198
pthread_mutex_destroy(mutex)
167199
mutex.deinitialize()
168200
mutex.deallocate(capacity: 1)
201+
#if os(OSX) || os(iOS)
202+
deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
203+
#endif
169204
}
170205

171206
open func lock() {
@@ -174,28 +209,40 @@ open class NSRecursiveLock: NSObject, NSLocking {
174209

175210
open func unlock() {
176211
pthread_mutex_unlock(mutex)
212+
#if os(OSX) || os(iOS)
213+
// Wakeup any threads waiting in lock(before:)
214+
pthread_mutex_lock(timeoutMutex)
215+
pthread_cond_broadcast(timeoutCond)
216+
pthread_mutex_unlock(timeoutMutex)
217+
#endif
177218
}
178219

179220
open func `try`() -> Bool {
180221
return pthread_mutex_trylock(mutex) == 0
181222
}
182223

183-
open func lock(before limit: Date) {
184-
NSUnimplemented()
224+
open func lock(before limit: Date) -> Bool {
225+
if pthread_mutex_trylock(mutex) == 0 {
226+
return true
227+
}
228+
229+
#if os(OSX) || os(iOS)
230+
return timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
231+
#else
232+
guard var endTime = timeSpecFrom(date: limit) else {
233+
return false
234+
}
235+
return pthread_mutex_timedlock(mutex, &endTime) == 0
236+
#endif
185237
}
186238

187239
open var name: String?
188240
}
189241

190242
open class NSCondition: NSObject, NSLocking {
191-
#if CYGWIN
192-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t?>.allocate(capacity: 1)
193-
internal var cond = UnsafeMutablePointer<pthread_cond_t?>.allocate(capacity: 1)
194-
#else
195-
internal var mutex = UnsafeMutablePointer<pthread_mutex_t>.allocate(capacity: 1)
196-
internal var cond = UnsafeMutablePointer<pthread_cond_t>.allocate(capacity: 1)
197-
#endif
198-
243+
internal var mutex = _PthreadMutexPointer.allocate(capacity: 1)
244+
internal var cond = _PthreadCondPointer.allocate(capacity: 1)
245+
199246
public override init() {
200247
pthread_mutex_init(mutex, nil)
201248
pthread_cond_init(cond, nil)
@@ -221,31 +268,12 @@ open class NSCondition: NSObject, NSLocking {
221268
open func wait() {
222269
pthread_cond_wait(cond, mutex)
223270
}
224-
271+
225272
open func wait(until limit: Date) -> Bool {
226-
let lim = limit.timeIntervalSinceReferenceDate
227-
let ti = lim - CFAbsoluteTimeGetCurrent()
228-
if ti < 0.0 {
273+
guard var timeout = timeSpecFrom(date: limit) else {
229274
return false
230275
}
231-
var ts = timespec()
232-
ts.tv_sec = Int(floor(ti))
233-
ts.tv_nsec = Int((ti - Double(ts.tv_sec)) * 1_000_000_000.0)
234-
var tv = timeval()
235-
withUnsafeMutablePointer(to: &tv) { t in
236-
gettimeofday(t, nil)
237-
ts.tv_sec += t.pointee.tv_sec
238-
ts.tv_nsec += Int(t.pointee.tv_usec) * 1000
239-
if ts.tv_nsec >= 1_000_000_000 {
240-
ts.tv_sec += ts.tv_nsec / 1_000_000_000
241-
ts.tv_nsec = ts.tv_nsec % 1_000_000_000
242-
}
243-
}
244-
let retVal: Int32 = withUnsafePointer(to: &ts) { t in
245-
return pthread_cond_timedwait(cond, mutex, t)
246-
}
247-
248-
return retVal == 0
276+
return pthread_cond_timedwait(cond, mutex, &timeout) == 0
249277
}
250278

251279
open func signal() {
@@ -258,3 +286,58 @@ open class NSCondition: NSObject, NSLocking {
258286

259287
open var name: String?
260288
}
289+
290+
private func timeSpecFrom(date: Date) -> timespec? {
291+
guard date.timeIntervalSinceNow > 0 else {
292+
return nil
293+
}
294+
let nsecPerSec: Int64 = 1_000_000_000
295+
let interval = date.timeIntervalSince1970
296+
let intervalNS = Int64(interval * Double(nsecPerSec))
297+
298+
return timespec(tv_sec: Int(intervalNS / nsecPerSec),
299+
tv_nsec: Int(intervalNS % nsecPerSec))
300+
}
301+
302+
#if os(OSX) || os(iOS)
303+
304+
private func deallocateTimedLockData(cond: _PthreadCondPointer, mutex: _PthreadMutexPointer) {
305+
pthread_cond_destroy(cond)
306+
cond.deinitialize()
307+
cond.deallocate(capacity: 1)
308+
309+
pthread_mutex_destroy(mutex)
310+
mutex.deinitialize()
311+
mutex.deallocate(capacity: 1)
312+
}
313+
314+
// Emulate pthread_mutex_timedlock using pthread_cond_timedwait.
315+
// lock(before:) passes a condition variable/mutex pair to use.
316+
// unlock() will use pthread_cond_broadcast() to wake any waits in progress.
317+
private func timedLock(mutex: _PthreadMutexPointer, endTime: Date,
318+
using timeoutCond: _PthreadCondPointer,
319+
with timeoutMutex: _PthreadMutexPointer) -> Bool {
320+
321+
var timeSpec = timeSpecFrom(date: endTime)
322+
while var ts = timeSpec {
323+
let lockval = pthread_mutex_lock(timeoutMutex)
324+
precondition(lockval == 0)
325+
let waitval = pthread_cond_timedwait(timeoutCond, timeoutMutex, &ts)
326+
precondition(waitval == 0 || waitval == ETIMEDOUT)
327+
let unlockval = pthread_mutex_unlock(timeoutMutex)
328+
precondition(unlockval == 0)
329+
330+
if waitval == ETIMEDOUT {
331+
return false
332+
}
333+
let tryval = pthread_mutex_trylock(mutex)
334+
precondition(tryval == 0 || tryval == EBUSY)
335+
if tryval == 0 { // The lock was obtained.
336+
return true
337+
}
338+
// pthread_cond_timedwait didnt timeout so wait some more.
339+
timeSpec = timeSpecFrom(date: endTime)
340+
}
341+
return false
342+
}
343+
#endif

Foundation/NSObject.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
88
//
99

10+
// @_exported import of Dispatch here makes it available to all
11+
// classes in Foundation and all sources that import Foundation.
12+
// This brings it into line with Darwin usage for compatbility.
13+
@_exported import Dispatch
14+
1015
import CoreFoundation
1116

1217
/// The `NSObjectProtocol` groups methods that are fundamental to all Foundation objects.

0 commit comments

Comments
 (0)