diff --git a/configure.ac b/configure.ac index de2165ab2..297517ed8 100644 --- a/configure.ac +++ b/configure.ac @@ -94,6 +94,8 @@ AS_IF([test "x$enable_apple_tsd_optimizations" = "xyes"], [Define to use non-portable pthread TSD optimizations for Mac OS X)])] ) +AC_CANONICAL_TARGET + # # Enable building Swift overlay support into libdispatch # @@ -102,17 +104,34 @@ AC_ARG_WITH([swift-toolchain], [swift_toolchain_path=${withval} AC_DEFINE(HAVE_SWIFT, 1, [Define if building for Swift]) SWIFTC="$swift_toolchain_path/bin/swiftc" + case $target_os in + linux*) + os_string="linux" + ;; + *) + os_string=$target_os + ;; + esac + SWIFT_LIBDIR="$swift_toolchain_path/lib/swift/$os_string/$target_cpu" have_swift=true], [have_swift=false] ) AM_CONDITIONAL(HAVE_SWIFT, $have_swift) AC_SUBST([SWIFTC]) +AC_SUBST([SWIFT_LIBDIR]) + +# +# Enable use of gold linker when building the Swift overlay +# to avoid a symbol relocation issue. +# Ultimately the request to use gold should be passed in as an arg +# +AC_CHECK_PROG(use_gold_linker, ld.gold, true, false) +AM_CONDITIONAL(USE_GOLD_LINKER, $use_gold_linker) # # Enable __thread based TSD on platforms where it is efficient # Allow override based on command line argument to configure # -AC_CANONICAL_TARGET AC_ARG_ENABLE([thread-local-storage], [AS_HELP_STRING([--enable-thread-local-storage], [Enable usage of thread local storage via __thread])],, diff --git a/dispatch/Makefile.am b/dispatch/Makefile.am index 53ea5986c..89fd3daf0 100644 --- a/dispatch/Makefile.am +++ b/dispatch/Makefile.am @@ -24,5 +24,5 @@ dispatch_HEADERS= \ time.h if HAVE_SWIFT -dispatch_HEADERS+=module.map +dispatch_HEADERS+=module.modulemap endif diff --git a/dispatch/module.map b/dispatch/module.map deleted file mode 100644 index eefa75159..000000000 --- a/dispatch/module.map +++ /dev/null @@ -1,7 +0,0 @@ -module Dispatch [system] { - umbrella header "dispatch.h" - requires blocks - export * - link "dispatch" - link "BlocksRuntime" -} diff --git a/dispatch/module.modulemap b/dispatch/module.modulemap index addaae436..6f3c8aab8 100644 --- a/dispatch/module.modulemap +++ b/dispatch/module.modulemap @@ -1,10 +1,20 @@ -module Dispatch [system] [extern_c] { - umbrella header "dispatch.h" - module * { export * } +module Dispatch { + requires blocks export * + link "dispatch" + link "BlocksRuntime" } module DispatchIntrospection [system] [extern_c] { header "introspection.h" export * } + +module CDispatch [system] [extern_c] { + umbrella header "dispatch.h" + module * { export * } + export * + requires blocks + link "dispatch" + link "BlocksRuntime" +} diff --git a/src/Makefile.am b/src/Makefile.am index e51d15a33..58fa4ef12 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,7 @@ libdispatch_la_SOURCES= \ source_internal.h \ trace.h \ voucher_internal.h \ + firehose/firehose_internal.h \ shims/atomic.h \ shims/atomic_sfb.h \ shims/getprogname.h \ @@ -83,6 +84,10 @@ libdispatch_la_LDFLAGS+=-Wl,-compatibility_version,1 \ -Wl,-alias_list,$(top_srcdir)/xcodeconfig/libdispatch.aliases endif +if USE_GOLD_LINKER +libdispatch_la_LDFLAGS+=-Xcompiler -fuse-ld=gold +endif + if USE_OBJC libdispatch_la_SOURCES+=block.cpp data.m object.m libdispatch_la_OBJCFLAGS=$(AM_OBJCFLAGS) -Wno-switch -fobjc-gc @@ -114,9 +119,7 @@ DTRACE_SOURCES=provider.h endif if HAVE_SWIFT -libdispatch_la_SOURCES+=swift/Dispatch.mm -EXTRA_libdispatch_la_SOURCES+= \ - swift/Dispatch.swift \ +SWIFT_SRC_FILES=\ swift/Block.swift \ swift/Data.swift \ swift/Dispatch.swift \ @@ -124,33 +127,52 @@ EXTRA_libdispatch_la_SOURCES+= \ swift/Private.swift \ swift/Queue.swift \ swift/Source.swift \ - swift/Time.swift - -EXTRA_libdispatch_la_DEPENDENCIES+=$(abs_builddir)/Dispatch.o $(abs_builddir)/Dispatch.swiftmodule -libdispatch_la_LIBADD+=$(abs_builddir)/Dispatch.o - -SWIFT_OBJECTS= \ - $(abs_builddir)/Dispatch.swiftmodule \ - $(abs_builddir)/Dispatch.swiftdoc \ - $(abs_builddir)/Dispatch.o + swift/Time.swift \ + swift/Wrapper.swift + +SWIFT_ABS_SRC_FILES = $(SWIFT_SRC_FILES:%=$(abs_srcdir)/%) +SWIFT_OBJ_FILES = $(SWIFT_SRC_FILES:%.swift=$(abs_builddir)/%.o) + +libdispatch_la_SOURCES+=swift/DispatchStubs.cc +EXTRA_libdispatch_la_SOURCES+=$(SWIFT_SRC_FILES) + +EXTRA_libdispatch_la_DEPENDENCIES+=$(SWIFT_OBJ_FILES) $(abs_builddir)/swift/Dispatch.swiftmodule +libdispatch_la_LIBADD+=$(SWIFT_OBJ_FILES) + +SWIFT_GEN_FILES= \ + $(abs_builddir)/swift/Dispatch.swiftmodule \ + $(abs_builddir)/swift/Dispatch.swiftdoc \ + $(SWIFT_OBJ_FILES) \ + $(SWIFT_OBJ_FILES:%=%.d) \ + $(SWIFT_OBJ_FILES:%=%.swiftdeps) \ + $(SWIFT_OBJ_FILES:%=%.~partial.swiftmodule) \ + $(SWIFT_OBJ_FILES:%=%.~partial.swiftdoc) \ + $(SWIFT_OBJ_FILES:%=%.~partial.swiftdeps) + +SWIFTC_FLAGS = -Xcc -D__DISPATCH_BUILDING_SWIFT_MODULE__=1 -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.modulemap -I$(abs_top_srcdir) -Xcc -fblocks + +$(abs_builddir)/swift/%.o: $(abs_srcdir)/swift/%.swift + $(SWIFTC) -frontend -c $(SWIFT_ABS_SRC_FILES) -primary-file $< \ + $(SWIFTC_FLAGS) -module-name Dispatch -module-link-name dispatch \ + -o $@ -emit-module-path $@.~partial.swiftmodule \ + -emit-module-doc-path $@.~partial.swiftdoc -emit-dependencies-path $@.d \ + -emit-reference-dependencies-path $@.swiftdeps \ + -module-cache-path $(top_builddir) + +$(abs_builddir)/swift/Dispatch.swiftmodule: $(SWIFT_ABS_SRC_FILES) + $(SWIFTC) -frontend -emit-module $(SWIFT_OBJ_FILES:%=%.~partial.swiftmodule) \ + $(SWIFTC_FLAGS) -module-cache-path $(top_builddir) -module-link-name dispatch \ + -o $@ -emit-module-doc-path $(@:%.swiftmodule=%.swiftdoc) -SWIFTC_FLAGS = -Xcc -D__DISPATCH_BUILDING_SWIFT_MODULE__=1 -Xcc -fmodule-map-file=$(abs_top_srcdir)/dispatch/module.map -I$(abs_top_srcdir) -parse-as-library -Xcc -fblocks - -$(abs_builddir)/Dispatch.o: $(abs_srcdir)/swift/Dispatch.swift - $(SWIFTC) $(SWIFTC_FLAGS) -c -o $@ $< - -$(abs_builddir)/Dispatch.swiftmodule: $(abs_srcdir)/swift/Dispatch.swift - $(SWIFTC) $(SWIFTC_FLAGS) -emit-module -emit-module-path $@ $< - -if HAVE_SWIFT swiftmoddir=${prefix}/lib/swift/linux/${build_cpu} -swiftmod_HEADERS=$(abs_builddir)/Dispatch.swiftmodule $(abs_builddir)/Dispatch.swiftdoc -endif +swiftmod_HEADERS=\ + $(abs_builddir)/swift/Dispatch.swiftmodule \ + $(abs_builddir)/swift/Dispatch.swiftdoc endif BUILT_SOURCES=$(MIG_SOURCES) $(DTRACE_SOURCES) nodist_libdispatch_la_SOURCES=$(BUILT_SOURCES) -CLEANFILES=$(BUILT_SOURCES) $(SWIFT_OBJECTS) +CLEANFILES=$(BUILT_SOURCES) $(SWIFT_GEN_FILES) DISTCLEANFILES=pthread_machdep.h pthread System mach objc diff --git a/src/data.c b/src/data.c index 33906d35d..5f1942fef 100644 --- a/src/data.c +++ b/src/data.c @@ -108,6 +108,10 @@ const dispatch_block_t _dispatch_data_destructor_none = ^{ DISPATCH_INTERNAL_CRASH(0, "none destructor called"); }; +const dispatch_block_t _dispatch_data_destructor_munmap = ^{ + DISPATCH_INTERNAL_CRASH(0, "munmap destructor called"); +}; + #ifndef __linux__ const dispatch_block_t _dispatch_data_destructor_vm_deallocate = ^{ DISPATCH_INTERNAL_CRASH(0, "vmdeallocate destructor called"); diff --git a/src/swift/Block.swift b/src/swift/Block.swift index e32478ea0..c1266cea1 100644 --- a/src/swift/Block.swift +++ b/src/swift/Block.swift @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +import CDispatch + public struct DispatchWorkItemFlags : OptionSet, RawRepresentable { public let rawValue: UInt public init(rawValue: UInt) { self.rawValue = rawValue } @@ -38,14 +40,14 @@ public class DispatchWorkItem { internal var _group: DispatchGroup? public init(group: DispatchGroup? = nil, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], block: @convention(block) () -> ()) { - _block = _swift_dispatch_block_create_with_qos_class(__dispatch_block_flags_t(flags.rawValue), - qos.qosClass.rawValue, Int32(qos.relativePriority), block) + _block = dispatch_block_create_with_qos_class(dispatch_block_flags_t(flags.rawValue), + qos.qosClass.rawValue.rawValue, Int32(qos.relativePriority), block) } // Used by DispatchQueue.synchronously to provide a @noescape path through // dispatch_block_t, as we know the lifetime of the block in question. internal init(flags: DispatchWorkItemFlags = [], noescapeBlock: @noescape () -> ()) { - _block = _swift_dispatch_block_create_noescape(__dispatch_block_flags_t(flags.rawValue), noescapeBlock) + _block = _swift_dispatch_block_create_noescape(dispatch_block_flags_t(flags.rawValue), noescapeBlock) } public func perform() { @@ -57,36 +59,36 @@ public class DispatchWorkItem { } public func wait() { - _ = _swift_dispatch_block_wait(_block, DispatchTime.distantFuture.rawValue) + _ = dispatch_block_wait(_block, DispatchTime.distantFuture.rawValue) } public func wait(timeout: DispatchTime) -> DispatchTimeoutResult { - return _swift_dispatch_block_wait(_block, timeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_block_wait(_block, timeout.rawValue) == 0 ? .Success : .TimedOut } public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult { - return _swift_dispatch_block_wait(_block, wallTimeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_block_wait(_block, wallTimeout.rawValue) == 0 ? .Success : .TimedOut } public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute: @convention(block) () -> Void) { if qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: execute) - _swift_dispatch_block_notify(_block, queue, item._block) + dispatch_block_notify(_block, queue.__wrapped, item._block) } else { - _swift_dispatch_block_notify(_block, queue, execute) + dispatch_block_notify(_block, queue.__wrapped, execute) } } public func notify(queue: DispatchQueue, execute: DispatchWorkItem) { - _swift_dispatch_block_notify(_block, queue, execute._block) + dispatch_block_notify(_block, queue.__wrapped, execute._block) } public func cancel() { - _swift_dispatch_block_cancel(_block) + dispatch_block_cancel(_block) } public var isCancelled: Bool { - return _swift_dispatch_block_testcancel(_block) != 0 + return dispatch_block_testcancel(_block) != 0 } } @@ -96,7 +98,7 @@ public extension DispatchWorkItem { public func wait(timeout: DispatchWallTime) -> Int { switch wait(wallTimeout: timeout) { case .Success: return 0 - case .TimedOut: return Int(KERN_OPERATION_TIMED_OUT) + case .TimedOut: return DispatchTimeoutResult.KERN_OPERATION_TIMED_OUT } } } @@ -106,26 +108,7 @@ public extension DispatchWorkItem { /// C blocks and Swift closures, which interferes with dispatch APIs that depend /// on the referential identity of a block. Particularly, dispatch_block_create. internal typealias _DispatchBlock = @convention(block) () -> Void - -/// APINotes also removes the old dispatch_block_t typedef from the Dispatch module -/// completely. In doing so it causes the dispatch_block_* API to lose their -/// @convention(block) attributes. As such, all of the entry points are shimmed -//// through Dispatch.mm with _DispatchBlock types. -@_silgen_name("_swift_dispatch_block_create_with_qos_class") -internal func _swift_dispatch_block_create_with_qos_class(_ flags: __dispatch_block_flags_t, _ qos: qos_class_t, _ relativePriority: Int32, _ block: _DispatchBlock) -> _DispatchBlock +internal typealias dispatch_block_t = @convention(block) () -> Void @_silgen_name("_swift_dispatch_block_create_noescape") -internal func _swift_dispatch_block_create_noescape(_ flags: __dispatch_block_flags_t, _ block: @noescape () -> ()) -> _DispatchBlock - -@_silgen_name("_swift_dispatch_block_wait") -internal func _swift_dispatch_block_wait(_ block: _DispatchBlock, _ timeout: UInt64) -> Int - -@_silgen_name("_swift_dispatch_block_notify") -internal func _swift_dispatch_block_notify(_ block: _DispatchBlock, _ queue: DispatchQueue, _ notifier: _DispatchBlock) - -@_silgen_name("_swift_dispatch_block_cancel") -internal func _swift_dispatch_block_cancel(_ block: _DispatchBlock) - -@_silgen_name("_swift_dispatch_block_testcancel") -internal func _swift_dispatch_block_testcancel(_ block: _DispatchBlock) -> Int - +internal func _swift_dispatch_block_create_noescape(_ flags: dispatch_block_flags_t, _ block: @noescape () -> ()) -> _DispatchBlock diff --git a/src/swift/Data.swift b/src/swift/Data.swift index a78bf5bca..0d21e27c0 100644 --- a/src/swift/Data.swift +++ b/src/swift/Data.swift @@ -10,13 +10,16 @@ // //===----------------------------------------------------------------------===// -public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { +import CDispatch + +public struct DispatchData : RandomAccessCollection { public typealias Iterator = DispatchDataIterator public typealias Index = Int public typealias Indices = DefaultRandomAccessIndices public static let empty: DispatchData = DispatchData(data: _swift_dispatch_data_empty()) +#if false /* FIXME: dragging in _TMBO (Objective-C) */ public enum Deallocator { /// Use `free` case free @@ -35,18 +38,18 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { } } } - - private var __wrapped: __DispatchData +#endif + internal var __wrapped: dispatch_data_t /// Initialize a `Data` with copied memory content. /// /// - parameter bytes: A pointer to the memory. It will be copied. /// - parameter count: The number of bytes to copy. public init(bytes buffer: UnsafeBufferPointer) { - __wrapped = __dispatch_data_create( + __wrapped = dispatch_data_create( buffer.baseAddress!, buffer.count, nil, _dispatch_data_destructor_default()) } - +#if false /* FIXME: dragging in _TMBO (Objective-C) */ /// Initialize a `Data` without copying the bytes. /// /// - parameter bytes: A pointer to the bytes. @@ -55,16 +58,15 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { public init(bytesNoCopy bytes: UnsafeBufferPointer, deallocator: Deallocator = .free) { let (q, b) = deallocator._deallocator - __wrapped = __dispatch_data_create( - bytes.baseAddress!, bytes.count, q, b) + __wrapped = dispatch_data_create(bytes.baseAddress!, bytes.count, q?.__wrapped, b) } - - internal init(data: __DispatchData) { +#endif + internal init(data: dispatch_data_t) { __wrapped = data } public var count: Int { - return __dispatch_data_get_size(__wrapped) + return CDispatch.dispatch_data_get_size(__wrapped) } public func withUnsafeBytes( @@ -72,7 +74,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { { var ptr: UnsafePointer? = nil var size = 0; - let data = __dispatch_data_create_map(__wrapped, &ptr, &size) + let data = CDispatch.dispatch_data_create_map(__wrapped, &ptr, &size) defer { _fixLifetime(data) } return try body(UnsafePointer(ptr!)) } @@ -80,7 +82,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { public func enumerateBytes( block: @noescape (buffer: UnsafeBufferPointer, byteIndex: Int, stop: inout Bool) -> Void) { - _swift_dispatch_data_apply(__wrapped) { (data: __DispatchData, offset: Int, ptr: UnsafePointer, size: Int) in + _swift_dispatch_data_apply(__wrapped) { (data: dispatch_data_t, offset: Int, ptr: UnsafePointer, size: Int) in let bp = UnsafeBufferPointer(start: UnsafePointer(ptr), count: size) var stop = false block(buffer: bp, byteIndex: offset, stop: &stop) @@ -93,7 +95,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { /// - parameter bytes: A pointer to the bytes to copy in to the data. /// - parameter count: The number of bytes to copy. public mutating func append(_ bytes: UnsafePointer, count: Int) { - let data = __dispatch_data_create(bytes, count, nil, _dispatch_data_destructor_default()) + let data = dispatch_data_create(bytes, count, nil, _dispatch_data_destructor_default()) self.append(DispatchData(data: data)) } @@ -101,7 +103,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { /// /// - parameter data: The data to append to this data. public mutating func append(_ other: DispatchData) { - let data = __dispatch_data_create_concat(__wrapped, other as __DispatchData) + let data = CDispatch.dispatch_data_create_concat(__wrapped, other.__wrapped) __wrapped = data } @@ -109,12 +111,12 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { /// /// - parameter buffer: The buffer of bytes to append. The size is calculated from `SourceType` and `buffer.count`. public mutating func append(_ buffer : UnsafeBufferPointer) { - self.append(UnsafePointer(buffer.baseAddress!), count: buffer.count * sizeof(SourceType)) + self.append(UnsafePointer(buffer.baseAddress!), count: buffer.count * sizeof(SourceType.self)) } private func _copyBytesHelper(to pointer: UnsafeMutablePointer, from range: CountableRange) { var copiedCount = 0 - __dispatch_data_apply(__wrapped) { (data: __DispatchData, offset: Int, ptr: UnsafePointer, size: Int) in + _ = CDispatch.dispatch_data_apply(__wrapped) { (data: dispatch_data_t, offset: Int, ptr: UnsafePointer, size: Int) in let limit = Swift.min((range.endIndex - range.startIndex) - copiedCount, size) memcpy(pointer + copiedCount, ptr, limit) copiedCount += limit @@ -160,9 +162,9 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { precondition(r.endIndex >= 0) precondition(r.endIndex <= cnt, "The range is outside the bounds of the data") - copyRange = r.startIndex..<(r.startIndex + Swift.min(buffer.count * sizeof(DestinationType), r.count)) + copyRange = r.startIndex..<(r.startIndex + Swift.min(buffer.count * sizeof(DestinationType.self), r.count)) } else { - copyRange = 0.. UInt8 { var offset = 0 - let subdata = __dispatch_data_copy_region(__wrapped, index, &offset) + let subdata = CDispatch.dispatch_data_copy_region(__wrapped, index, &offset) var ptr: UnsafePointer? = nil var size = 0 - let map = __dispatch_data_create_map(subdata, &ptr, &size) + let map = CDispatch.dispatch_data_create_map(subdata, &ptr, &size) defer { _fixLifetime(map) } let pptr = UnsafePointer(ptr!) @@ -194,14 +196,14 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable { /// /// - parameter range: The range to copy. public func subdata(in range: CountableRange) -> DispatchData { - let subrange = __dispatch_data_create_subrange( + let subrange = CDispatch.dispatch_data_create_subrange( __wrapped, range.startIndex, range.endIndex - range.startIndex) return DispatchData(data: subrange) } public func region(location: Int) -> (data: DispatchData, offset: Int) { var offset: Int = 0 - let data = __dispatch_data_copy_region(__wrapped, location, &offset) + let data = CDispatch.dispatch_data_copy_region(__wrapped, location, &offset) return (DispatchData(data: data), offset) } @@ -235,8 +237,7 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence { public init(_data: DispatchData) { var ptr: UnsafePointer? self._count = 0 - self._data = __dispatch_data_create_map( - _data as __DispatchData, &ptr, &self._count) + self._data = CDispatch.dispatch_data_create_map(_data.__wrapped, &ptr, &self._count) self._ptr = UnsafePointer(ptr!) self._position = _data.startIndex } @@ -252,45 +253,19 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence { return element } - internal let _data: __DispatchData + internal let _data: dispatch_data_t internal var _ptr: UnsafePointer internal var _count: Int internal var _position: DispatchData.Index } -extension DispatchData { - public static func _isBridgedToObjectiveC() -> Bool { - return true - } - - @_semantics("convertToObjectiveC") - public func _bridgeToObjectiveC() -> __DispatchData { - return unsafeBitCast(__wrapped, to: __DispatchData.self) - } - - public static func _forceBridgeFromObjectiveC(_ input: __DispatchData, result: inout DispatchData?) { - result = DispatchData(data: input) - } - - public static func _conditionallyBridgeFromObjectiveC(_ input: __DispatchData, result: inout DispatchData?) -> Bool { - result = DispatchData(data: input) - return true - } - - public static func _unconditionallyBridgeFromObjectiveC(_ source: __DispatchData?) -> DispatchData { - var result: DispatchData? = nil - _forceBridgeFromObjectiveC(source!, result: &result) - return result! - } -} - -typealias _swift_data_applier = @convention(block) @noescape (__DispatchData, Int, UnsafePointer, Int) -> Bool +typealias _swift_data_applier = @convention(block) @noescape (dispatch_data_t, Int, UnsafePointer, Int) -> Bool @_silgen_name("_swift_dispatch_data_apply") -internal func _swift_dispatch_data_apply(_ data: __DispatchData, _ block: _swift_data_applier) +internal func _swift_dispatch_data_apply(_ data: dispatch_data_t, _ block: _swift_data_applier) @_silgen_name("_swift_dispatch_data_empty") -internal func _swift_dispatch_data_empty() -> __DispatchData +internal func _swift_dispatch_data_empty() -> dispatch_data_t @_silgen_name("_swift_dispatch_data_destructor_free") internal func _dispatch_data_destructor_free() -> _DispatchBlock diff --git a/src/swift/Dispatch.swift b/src/swift/Dispatch.swift index 4ed2ad9cd..2b9cb2164 100644 --- a/src/swift/Dispatch.swift +++ b/src/swift/Dispatch.swift @@ -12,6 +12,8 @@ @_exported import Dispatch +import CDispatch + /// dispatch_assert @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) @@ -25,11 +27,11 @@ public enum DispatchPredicate { public func _dispatchPreconditionTest(_ condition: DispatchPredicate) -> Bool { switch condition { case .onQueue(let q): - __dispatch_assert_queue(q) + dispatch_assert_queue(q.__wrapped) case .onQueueAsBarrier(let q): - __dispatch_assert_queue_barrier(q) + dispatch_assert_queue_barrier(q.__wrapped) case .notOnQueue(let q): - __dispatch_assert_queue_not(q) + dispatch_assert_queue_not(q.__wrapped) } return true } @@ -94,27 +96,27 @@ public struct DispatchQoS : Equatable { case unspecified @available(OSX 10.10, iOS 8.0, *) - internal init?(qosClass: qos_class_t) { + internal init?(qosClass: _OSQoSClass) { switch qosClass { - case QOS_CLASS_BACKGROUND: self = .background - case QOS_CLASS_UTILITY: self = .utility - case QOS_CLASS_DEFAULT: self = .default - case QOS_CLASS_USER_INITIATED: self = .userInitiated - case QOS_CLASS_USER_INTERACTIVE: self = .userInteractive - case QOS_CLASS_UNSPECIFIED: self = .unspecified + case .QOS_CLASS_BACKGROUND: self = .background + case .QOS_CLASS_UTILITY: self = .utility + case .QOS_CLASS_DEFAULT: self = .default + case .QOS_CLASS_USER_INITIATED: self = .userInitiated + case .QOS_CLASS_USER_INTERACTIVE: self = .userInteractive + case .QOS_CLASS_UNSPECIFIED: self = .unspecified default: return nil } } @available(OSX 10.10, iOS 8.0, *) - internal var rawValue: qos_class_t { + internal var rawValue: _OSQoSClass { switch self { - case .background: return QOS_CLASS_BACKGROUND - case .utility: return QOS_CLASS_UTILITY - case .default: return QOS_CLASS_DEFAULT - case .userInitiated: return QOS_CLASS_USER_INITIATED - case .userInteractive: return QOS_CLASS_USER_INTERACTIVE - case .unspecified: return QOS_CLASS_UNSPECIFIED + case .background: return .QOS_CLASS_BACKGROUND + case .utility: return .QOS_CLASS_UTILITY + case .default: return .QOS_CLASS_DEFAULT + case .userInitiated: return .QOS_CLASS_USER_INITIATED + case .userInteractive: return .QOS_CLASS_USER_INTERACTIVE + case .unspecified: return .QOS_CLASS_UNSPECIFIED } } } @@ -132,6 +134,7 @@ public func ==(a: DispatchQoS, b: DispatchQoS) -> Bool { /// public enum DispatchTimeoutResult { + static let KERN_OPERATION_TIMED_OUT:Int = 49 case Success case TimedOut } @@ -142,27 +145,27 @@ public extension DispatchGroup { public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @convention(block) () -> ()) { if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: work) - __dispatch_group_notify(self, queue, item._block) + dispatch_group_notify(self.__wrapped, queue.__wrapped, item._block) } else { - __dispatch_group_notify(self, queue, work) + dispatch_group_notify(self.__wrapped, queue.__wrapped, work) } } @available(OSX 10.10, iOS 8.0, *) public func notify(queue: DispatchQueue, work: DispatchWorkItem) { - __dispatch_group_notify(self, queue, work._block) + dispatch_group_notify(self.__wrapped, queue.__wrapped, work._block) } public func wait() { - _ = __dispatch_group_wait(self, DispatchTime.distantFuture.rawValue) + _ = dispatch_group_wait(self.__wrapped, DispatchTime.distantFuture.rawValue) } public func wait(timeout: DispatchTime) -> DispatchTimeoutResult { - return __dispatch_group_wait(self, timeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut } public func wait(wallTimeout timeout: DispatchWallTime) -> DispatchTimeoutResult { - return __dispatch_group_wait(self, timeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_group_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut } } @@ -171,7 +174,7 @@ public extension DispatchGroup { public func wait(walltime timeout: DispatchWallTime) -> Int { switch wait(wallTimeout: timeout) { case .Success: return 0 - case .TimedOut: return Int(KERN_OPERATION_TIMED_OUT) + case .TimedOut: return DispatchTimeoutResult.KERN_OPERATION_TIMED_OUT } } } @@ -181,19 +184,19 @@ public extension DispatchGroup { public extension DispatchSemaphore { @discardableResult public func signal() -> Int { - return __dispatch_semaphore_signal(self) + return dispatch_semaphore_signal(self.__wrapped) } public func wait() { - _ = __dispatch_semaphore_wait(self, DispatchTime.distantFuture.rawValue) + _ = dispatch_semaphore_wait(self.__wrapped, DispatchTime.distantFuture.rawValue) } public func wait(timeout: DispatchTime) -> DispatchTimeoutResult { - return __dispatch_semaphore_wait(self, timeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_semaphore_wait(self.__wrapped, timeout.rawValue) == 0 ? .Success : .TimedOut } public func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult { - return __dispatch_semaphore_wait(self, wallTimeout.rawValue) == 0 ? .Success : .TimedOut + return dispatch_semaphore_wait(self.__wrapped, wallTimeout.rawValue) == 0 ? .Success : .TimedOut } } @@ -202,7 +205,7 @@ public extension DispatchSemaphore { public func wait(walltime timeout: DispatchWalltime) -> Int { switch wait(wallTimeout: timeout) { case .Success: return 0 - case .TimedOut: return Int(KERN_OPERATION_TIMED_OUT) + case .TimedOut: return DispatchTimeoutResult.KERN_OPERATION_TIMED_OUT } } } diff --git a/src/swift/Dispatch.mm b/src/swift/DispatchStubs.cc similarity index 89% rename from src/swift/Dispatch.mm rename to src/swift/DispatchStubs.cc index b66a34e8b..62a53ef6b 100644 --- a/src/swift/Dispatch.mm +++ b/src/swift/DispatchStubs.cc @@ -11,11 +11,11 @@ //===----------------------------------------------------------------------===// #include -#include #include #define DISPATCH_RUNTIME_STDLIB_INTERFACE __attribute__((__visibility__("default"))) +#if USE_OBJC @protocol OS_dispatch_source; @protocol OS_dispatch_source_mach_send; @protocol OS_dispatch_source_mach_recv; @@ -49,9 +49,15 @@ static void _dispatch_overlay_constructor() { } } +#endif /* USE_OBJC */ + +#if 0 /* FIXME -- adding directory to include path may need build-script plumbing to do properly... */ #include "swift/Runtime/Config.h" +#else +#define SWIFT_CC(x) /* FIXME!! */ +#endif -SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE +SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_queue_attr_t _swift_dispatch_queue_concurrent(void) { return DISPATCH_QUEUE_CONCURRENT; @@ -95,7 +101,7 @@ static void _dispatch_overlay_constructor() { SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_block_t -_swift_dispatch_block_create_with_qos_class(dispatch_block_flags_t flags, qos_class_t qos, int relative_priority, dispatch_block_t block) { +_swift_dispatch_block_create_with_qos_class(dispatch_block_flags_t flags, dispatch_qos_class_t qos, int relative_priority, dispatch_block_t block) { return dispatch_block_create_with_qos_class(flags, qos, relative_priority, block); } @@ -168,12 +174,28 @@ static void _dispatch_overlay_constructor() { SOURCE(DATA_ADD) SOURCE(DATA_OR) +#if HAVE_MACH SOURCE(MACH_SEND) SOURCE(MACH_RECV) SOURCE(MEMORYPRESSURE) +#endif +#ifndef __linux__ SOURCE(PROC) +#endif SOURCE(READ) SOURCE(SIGNAL) SOURCE(TIMER) +#ifndef __linux__ SOURCE(VNODE) +#endif SOURCE(WRITE) + +// See comment in CFFuntime.c explaining why objc_retainAutoreleasedReturnValue is needed. +extern "C" void swift_release(void *); +extern "C" void * objc_retainAutoreleasedReturnValue(void *obj) { + if (obj) { + swift_release(obj); + return obj; + } + else return NULL; +} diff --git a/src/swift/IO.swift b/src/swift/IO.swift index 049f54f3c..6e6b6692e 100644 --- a/src/swift/IO.swift +++ b/src/swift/IO.swift @@ -10,6 +10,8 @@ // //===----------------------------------------------------------------------===// +import CDispatch + public extension DispatchIO { public enum StreamType : UInt { @@ -33,13 +35,13 @@ public extension DispatchIO { } public class func read(fromFileDescriptor: Int32, maxLength: Int, runningHandlerOn queue: DispatchQueue, handler: (data: DispatchData, error: Int32) -> Void) { - __dispatch_read(fromFileDescriptor, maxLength, queue) { (data: __DispatchData, error: Int32) in + dispatch_read(fromFileDescriptor, maxLength, queue.__wrapped) { (data: dispatch_data_t, error: Int32) in handler(data: DispatchData(data: data), error: error) } } public class func write(fromFileDescriptor: Int32, data: DispatchData, runningHandlerOn queue: DispatchQueue, handler: (data: DispatchData?, error: Int32) -> Void) { - __dispatch_write(fromFileDescriptor, data as __DispatchData, queue) { (data: __DispatchData?, error: Int32) in + dispatch_write(fromFileDescriptor, data.__wrapped, queue.__wrapped) { (data: dispatch_data_t?, error: Int32) in handler(data: data.flatMap { DispatchData(data: $0) }, error: error) } } @@ -74,23 +76,23 @@ public extension DispatchIO { } public func read(offset: off_t, length: Int, queue: DispatchQueue, ioHandler: (done: Bool, data: DispatchData?, error: Int32) -> Void) { - __dispatch_io_read(self, offset, length, queue) { (done: Bool, data: __DispatchData?, error: Int32) in + dispatch_io_read(self.__wrapped, offset, length, queue.__wrapped) { (done: Bool, data: dispatch_data_t?, error: Int32) in ioHandler(done: done, data: data.flatMap { DispatchData(data: $0) }, error: error) } } public func write(offset: off_t, data: DispatchData, queue: DispatchQueue, ioHandler: (done: Bool, data: DispatchData?, error: Int32) -> Void) { - __dispatch_io_write(self, offset, data as __DispatchData, queue) { (done: Bool, data: __DispatchData?, error: Int32) in + dispatch_io_write(self.__wrapped, offset, data.__wrapped, queue.__wrapped) { (done: Bool, data: dispatch_data_t?, error: Int32) in ioHandler(done: done, data: data.flatMap { DispatchData(data: $0) }, error: error) } } public func setInterval(interval: DispatchTimeInterval, flags: IntervalFlags = []) { - __dispatch_io_set_interval(self, interval.rawValue, flags.rawValue) + dispatch_io_set_interval(self.__wrapped, interval.rawValue, flags.rawValue) } public func close(flags: CloseFlags = []) { - __dispatch_io_close(self, flags.rawValue) + dispatch_io_close(self.__wrapped, flags.rawValue) } } diff --git a/src/swift/Private.swift b/src/swift/Private.swift index 3a0cdb630..e38f72861 100644 --- a/src/swift/Private.swift +++ b/src/swift/Private.swift @@ -12,14 +12,16 @@ // Redeclarations of all SwiftPrivate functions with appropriate markup. +import CDispatch + @available(*, unavailable, renamed:"DispatchQueue.init(label:attributes:target:)") -public func dispatch_queue_create(_ label: UnsafePointer?, _ attr: __OS_dispatch_queue_attr?) -> DispatchQueue +public func dispatch_queue_create(_ label: UnsafePointer?, _ attr: dispatch_queue_attr_t?) -> DispatchQueue { fatalError() } @available(*, unavailable, renamed:"DispatchQueue.init(label:attributes:target:)") -public func dispatch_queue_create_with_target(_ label: UnsafePointer?, _ attr: __OS_dispatch_queue_attr?, _ queue: DispatchQueue?) -> DispatchQueue +public func dispatch_queue_create_with_target(_ label: UnsafePointer?, _ attr: dispatch_queue_attr_t?, _ queue: DispatchQueue?) -> DispatchQueue { fatalError() } @@ -43,67 +45,67 @@ public func dispatch_io_create_with_io(_ type: UInt, _ io: DispatchIO, _ queue: } @available(*, unavailable, renamed:"DispatchIO.read(fileDescriptor:length:queue:handler:)") -public func dispatch_read(_ fd: Int32, _ length: Int, _ queue: DispatchQueue, _ handler: (__DispatchData, Int32) -> Void) +public func dispatch_read(_ fd: Int32, _ length: Int, _ queue: DispatchQueue, _ handler: (dispatch_data_t, Int32) -> Void) { fatalError() } @available(*, unavailable, renamed:"DispatchIO.read(self:offset:length:queue:ioHandler:)") -func dispatch_io_read(_ channel: DispatchIO, _ offset: off_t, _ length: Int, _ queue: DispatchQueue, _ io_handler: (Bool, __DispatchData?, Int32) -> Void) +func dispatch_io_read(_ channel: DispatchIO, _ offset: off_t, _ length: Int, _ queue: DispatchQueue, _ io_handler: (Bool, dispatch_data_t?, Int32) -> Void) { fatalError() } @available(*, unavailable, renamed:"DispatchIO.write(self:offset:data:queue:ioHandler:)") -func dispatch_io_write(_ channel: DispatchIO, _ offset: off_t, _ data: __DispatchData, _ queue: DispatchQueue, _ io_handler: (Bool, __DispatchData?, Int32) -> Void) +func dispatch_io_write(_ channel: DispatchIO, _ offset: off_t, _ data: dispatch_data_t, _ queue: DispatchQueue, _ io_handler: (Bool, dispatch_data_t?, Int32) -> Void) { fatalError() } @available(*, unavailable, renamed:"DispatchIO.write(fileDescriptor:data:queue:handler:)") -func dispatch_write(_ fd: Int32, _ data: __DispatchData, _ queue: DispatchQueue, _ handler: (__DispatchData?, Int32) -> Void) +func dispatch_write(_ fd: Int32, _ data: dispatch_data_t, _ queue: DispatchQueue, _ handler: (dispatch_data_t?, Int32) -> Void) { fatalError() } @available(*, unavailable, renamed:"DispatchData.init(bytes:)") -public func dispatch_data_create(_ buffer: UnsafePointer, _ size: Int, _ queue: DispatchQueue?, _ destructor: (() -> Void)?) -> __DispatchData +public func dispatch_data_create(_ buffer: UnsafePointer, _ size: Int, _ queue: DispatchQueue?, _ destructor: (() -> Void)?) -> dispatch_data_t { fatalError() } @available(*, unavailable, renamed:"getter:DispatchData.count(self:)") -public func dispatch_data_get_size(_ data: __DispatchData) -> Int +public func dispatch_data_get_size(_ data: dispatch_data_t) -> Int { fatalError() } @available(*, unavailable, renamed:"DispatchData.withUnsafeBytes(self:body:)") -public func dispatch_data_create_map(_ data: __DispatchData, _ buffer_ptr: UnsafeMutablePointer?>?, _ size_ptr: UnsafeMutablePointer?) -> __DispatchData +public func dispatch_data_create_map(_ data: dispatch_data_t, _ buffer_ptr: UnsafeMutablePointer?>?, _ size_ptr: UnsafeMutablePointer?) -> dispatch_data_t { fatalError() } @available(*, unavailable, renamed:"DispatchData.append(self:_:)") -public func dispatch_data_create_concat(_ data1: __DispatchData, _ data2: __DispatchData) -> __DispatchData +public func dispatch_data_create_concat(_ data1: dispatch_data_t, _ data2: dispatch_data_t) -> dispatch_data_t { fatalError() } @available(*, unavailable, renamed:"DispatchData.subdata(self:in:)") -public func dispatch_data_create_subrange(_ data: __DispatchData, _ offset: Int, _ length: Int) -> __DispatchData +public func dispatch_data_create_subrange(_ data: dispatch_data_t, _ offset: Int, _ length: Int) -> dispatch_data_t { fatalError() } @available(*, unavailable, renamed:"DispatchData.enumerateBytes(self:block:)") -public func dispatch_data_apply(_ data: __DispatchData, _ applier: (__DispatchData, Int, UnsafePointer, Int) -> Bool) -> Bool +public func dispatch_data_apply(_ data: dispatch_data_t, _ applier: (dispatch_data_t, Int, UnsafePointer, Int) -> Bool) -> Bool { fatalError() } @available(*, unavailable, renamed:"DispatchData.region(self:location:)") -public func dispatch_data_copy_region(_ data: __DispatchData, _ location: Int, _ offset_ptr: UnsafeMutablePointer) -> __DispatchData +public func dispatch_data_copy_region(_ data: dispatch_data_t, _ location: Int, _ offset_ptr: UnsafeMutablePointer) -> dispatch_data_t { fatalError() } @@ -163,19 +165,19 @@ public func dispatch_get_main_queue() -> DispatchQueue } @available(*, unavailable, renamed:"DispatchQueueAttributes.initiallyInactive") -public func dispatch_queue_attr_make_initially_inactive(_ attr: __OS_dispatch_queue_attr?) -> __OS_dispatch_queue_attr +public func dispatch_queue_attr_make_initially_inactive(_ attr: dispatch_queue_attr_t?) -> dispatch_queue_attr_t { fatalError() } @available(*, unavailable, renamed:"DispatchQueueAttributes.autoreleaseWorkItem") -public func dispatch_queue_attr_make_with_autorelease_frequency(_ attr: __OS_dispatch_queue_attr?, _ frequency: __dispatch_autorelease_frequency_t) -> __OS_dispatch_queue_attr +public func dispatch_queue_attr_make_with_autorelease_frequency(_ attr: dispatch_queue_attr_t?, _ frequency: dispatch_autorelease_frequency_t) -> dispatch_queue_attr_t { fatalError() } @available(*, unavailable, renamed:"DispatchQueueAttributes.qosUserInitiated") -public func dispatch_queue_attr_make_with_qos_class(_ attr: __OS_dispatch_queue_attr?, _ qos_class: qos_class_t, _ relative_priority: Int32) -> __OS_dispatch_queue_attr +public func dispatch_queue_attr_make_with_qos_class(_ attr: dispatch_queue_attr_t?, _ qos_class: dispatch_qos_class_t, _ relative_priority: Int32) -> dispatch_queue_attr_t { fatalError() } @@ -187,7 +189,7 @@ public func dispatch_queue_get_label(_ queue: DispatchQueue?) -> UnsafePointer?) -> qos_class_t +public func dispatch_queue_get_qos_class(_ queue: DispatchQueue, _ relative_priority_ptr: UnsafeMutablePointer?) -> dispatch_qos_class_t { fatalError() } @@ -259,7 +261,7 @@ public func dispatch_semaphore_signal(_ dsema: DispatchSemaphore) -> Int } @available(*, unavailable, message:"Use DispatchSource class methods") -public func dispatch_source_create(_ type: __dispatch_source_type_t, _ handle: UInt, _ mask: UInt, _ queue: DispatchQueue?) -> DispatchSource +public func dispatch_source_create(_ type: dispatch_source_type_t, _ handle: UInt, _ mask: UInt, _ queue: DispatchQueue?) -> DispatchSource { fatalError() } diff --git a/src/swift/Queue.swift b/src/swift/Queue.swift index 6f7b541e9..1710846f0 100644 --- a/src/swift/Queue.swift +++ b/src/swift/Queue.swift @@ -12,6 +12,8 @@ // dispatch/queue.h +import CDispatch + public struct DispatchQueueAttributes : OptionSet { public let rawValue: UInt64 public init(rawValue: UInt64) { self.rawValue = rawValue } @@ -49,38 +51,38 @@ public struct DispatchQueueAttributes : OptionSet { @available(*, deprecated, message: ".noQoS has no effect, it should not be used") public static let noQoS = DispatchQueueAttributes(rawValue: 1<<11) - private var attr: __OS_dispatch_queue_attr? { - var attr: __OS_dispatch_queue_attr? + private var attr: dispatch_queue_attr_t? { + var attr: dispatch_queue_attr_t? if self.contains(.concurrent) { attr = _swift_dispatch_queue_concurrent() } if #available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) { if self.contains(.initiallyInactive) { - attr = __dispatch_queue_attr_make_initially_inactive(attr) + attr = CDispatch.dispatch_queue_attr_make_initially_inactive(attr) } if self.contains(.autoreleaseWorkItem) { // DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM - attr = __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(1)) + attr = CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(1)) } else if self.contains(.autoreleaseInherit) { // DISPATCH_AUTORELEASE_FREQUENCY_INHERIT - attr = __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(0)) + attr = CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(0)) } else if self.contains(.autoreleaseNever) { // DISPATCH_AUTORELEASE_FREQUENCY_NEVER - attr = __dispatch_queue_attr_make_with_autorelease_frequency(attr, __dispatch_autorelease_frequency_t(2)) + attr = CDispatch.dispatch_queue_attr_make_with_autorelease_frequency(attr, dispatch_autorelease_frequency_t(2)) } } if #available(OSX 10.10, iOS 8.0, *) { if self.contains(.qosUserInteractive) { - attr = __dispatch_queue_attr_make_with_qos_class(attr, QOS_CLASS_USER_INTERACTIVE, 0) + attr = CDispatch.dispatch_queue_attr_make_with_qos_class(attr, _OSQoSClass.QOS_CLASS_USER_INTERACTIVE.rawValue, 0) } else if self.contains(.qosUserInitiated) { - attr = __dispatch_queue_attr_make_with_qos_class(attr, QOS_CLASS_USER_INITIATED, 0) + attr = CDispatch.dispatch_queue_attr_make_with_qos_class(attr, _OSQoSClass.QOS_CLASS_USER_INITIATED.rawValue, 0) } else if self.contains(.qosDefault) { - attr = __dispatch_queue_attr_make_with_qos_class(attr, QOS_CLASS_DEFAULT, 0) + attr = CDispatch.dispatch_queue_attr_make_with_qos_class(attr, _OSQoSClass.QOS_CLASS_DEFAULT.rawValue, 0) } else if self.contains(.qosUtility) { - attr = __dispatch_queue_attr_make_with_qos_class(attr, QOS_CLASS_UTILITY, 0) + attr = CDispatch.dispatch_queue_attr_make_with_qos_class(attr, _OSQoSClass.QOS_CLASS_UTILITY.rawValue, 0) } else if self.contains(.qosBackground) { - attr = __dispatch_queue_attr_make_with_qos_class(attr, QOS_CLASS_BACKGROUND, 0) + attr = CDispatch.dispatch_queue_attr_make_with_qos_class(attr, _OSQoSClass.QOS_CLASS_BACKGROUND.rawValue, 0) } } return attr @@ -143,11 +145,11 @@ public extension DispatchQueue { internal var _translatedValue: Int { if #available(OSX 10.10, iOS 8.0, *) { - if self.contains(.qosUserInteractive) { return Int(QOS_CLASS_USER_INTERACTIVE.rawValue) } - else if self.contains(.qosUserInitiated) { return Int(QOS_CLASS_USER_INITIATED.rawValue) } - else if self.contains(.qosDefault) { return Int(QOS_CLASS_DEFAULT.rawValue) } - else if self.contains(.qosUtility) { return Int(QOS_CLASS_UTILITY.rawValue) } - else { return Int(QOS_CLASS_BACKGROUND.rawValue) } + if self.contains(.qosUserInteractive) { return Int(_OSQoSClass.QOS_CLASS_USER_INTERACTIVE.rawValue) } + else if self.contains(.qosUserInitiated) { return Int(_OSQoSClass.QOS_CLASS_USER_INITIATED.rawValue) } + else if self.contains(.qosDefault) { return Int(_OSQoSClass.QOS_CLASS_DEFAULT.rawValue) } + else if self.contains(.qosUtility) { return Int(_OSQoSClass.QOS_CLASS_UTILITY.rawValue) } + else { return Int(_OSQoSClass.QOS_CLASS_BACKGROUND.rawValue) } } if self.contains(._priorityHigh) { return 2 } // DISPATCH_QUEUE_PRIORITY_HIGH else if self.contains(._priorityDefault) { return 0 } // DISPATCH_QUEUE_PRIORITY_DEFAULT @@ -162,16 +164,17 @@ public extension DispatchQueue { } public class var main: DispatchQueue { - return _swift_dispatch_get_main_queue() + return DispatchQueue(queue: _swift_dispatch_get_main_queue()) } public class func global(attributes: GlobalAttributes = []) -> DispatchQueue { - return __dispatch_get_global_queue(attributes._translatedValue, 0) + // SubOptimal? Should we be caching these global DispatchQueue objects? + return DispatchQueue(queue:dispatch_get_global_queue(attributes._translatedValue, 0)) } public class func getSpecific(key: DispatchSpecificKey) -> T? { let k = Unmanaged.passUnretained(key).toOpaque() - if let p = __dispatch_get_specific(k) { + if let p = CDispatch.dispatch_get_specific(k) { let v = Unmanaged<_DispatchSpecificValue> .fromOpaque(p) .takeUnretainedValue() @@ -194,14 +197,12 @@ public extension DispatchQueue { } public var label: String { - return String(validatingUTF8: __dispatch_queue_get_label(self))! + return String(validatingUTF8: dispatch_queue_get_label(self.__wrapped))! } @available(OSX 10.10, iOS 8.0, *) public func sync(execute workItem: DispatchWorkItem) { - // _swift_dispatch_sync preserves the @convention(block) for - // work item blocks. - _swift_dispatch_sync(self, workItem._block) + dispatch_sync(self.__wrapped, workItem._block) } @available(OSX 10.10, iOS 8.0, *) @@ -209,37 +210,37 @@ public extension DispatchQueue { // _swift_dispatch_{group,}_async preserves the @convention(block) // for work item blocks. if let g = workItem._group { - _swift_dispatch_group_async(g, self, workItem._block) + dispatch_group_async(g.__wrapped, self.__wrapped, workItem._block) } else { - _swift_dispatch_async(self, workItem._block) + dispatch_async(self.__wrapped, workItem._block) } } public func async(group: DispatchGroup? = nil, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @convention(block) () -> Void) { if group == nil && qos == .unspecified && flags.isEmpty { // Fast-path route for the most common API usage - __dispatch_async(self, work) + dispatch_async(self.__wrapped, work) return } if #available(OSX 10.10, iOS 8.0, *), (qos != .unspecified || !flags.isEmpty) { let workItem = DispatchWorkItem(qos: qos, flags: flags, block: work) if let g = group { - _swift_dispatch_group_async(g, self, workItem._block) + dispatch_group_async(g.__wrapped, self.__wrapped, workItem._block) } else { - _swift_dispatch_async(self, workItem._block) + dispatch_async(self.__wrapped, workItem._block) } } else { if let g = group { - __dispatch_group_async(g, self, work) + dispatch_group_async(g.__wrapped, self.__wrapped, work) } else { - __dispatch_async(self, work) + dispatch_async(self.__wrapped, work) } } } private func _syncBarrier(block: @noescape () -> ()) { - __dispatch_barrier_sync(self, block) + dispatch_barrier_sync(self.__wrapped, block) } private func _syncHelper( @@ -304,41 +305,41 @@ public extension DispatchQueue { public func after(when: DispatchTime, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @convention(block) () -> Void) { if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: work) - __dispatch_after(when.rawValue, self, item._block) + dispatch_after(when.rawValue, self.__wrapped, item._block) } else { - __dispatch_after(when.rawValue, self, work) + dispatch_after(when.rawValue, self.__wrapped, work) } } @available(OSX 10.10, iOS 8.0, *) public func after(when: DispatchTime, execute: DispatchWorkItem) { - __dispatch_after(when.rawValue, self, execute._block) + dispatch_after(when.rawValue, self.__wrapped, execute._block) } public func after(walltime when: DispatchWallTime, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], execute work: @convention(block) () -> Void) { if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: work) - __dispatch_after(when.rawValue, self, item._block) + dispatch_after(when.rawValue, self.__wrapped, item._block) } else { - __dispatch_after(when.rawValue, self, work) + dispatch_after(when.rawValue, self.__wrapped, work) } } @available(OSX 10.10, iOS 8.0, *) public func after(walltime when: DispatchWallTime, execute: DispatchWorkItem) { - __dispatch_after(when.rawValue, self, execute._block) + dispatch_after(when.rawValue, self.__wrapped, execute._block) } @available(OSX 10.10, iOS 8.0, *) public var qos: DispatchQoS { var relPri: Int32 = 0 - let cls = DispatchQoS.QoSClass(qosClass: __dispatch_queue_get_qos_class(self, &relPri))! + let cls = DispatchQoS.QoSClass(qosClass: _OSQoSClass(qosClass: dispatch_queue_get_qos_class(self.__wrapped, &relPri))!)! return DispatchQoS(qosClass: cls, relativePriority: Int(relPri)) } public func getSpecific(key: DispatchSpecificKey) -> T? { let k = Unmanaged.passUnretained(key).toOpaque() - if let p = __dispatch_queue_get_specific(self, k) { + if let p = dispatch_queue_get_specific(self.__wrapped, k) { let v = Unmanaged<_DispatchSpecificValue> .fromOpaque(p) .takeUnretainedValue() @@ -351,7 +352,7 @@ public extension DispatchQueue { let v = _DispatchSpecificValue(value: value) let k = Unmanaged.passUnretained(key).toOpaque() let p = Unmanaged.passRetained(v).toOpaque() - __dispatch_queue_set_specific(self, k, p, _destructDispatchSpecificValue) + dispatch_queue_set_specific(self.__wrapped, k, p, _destructDispatchSpecificValue) } } @@ -408,22 +409,13 @@ private func _destructDispatchSpecificValue(ptr: UnsafeMutablePointer?) { } @_silgen_name("_swift_dispatch_queue_concurrent") -internal func _swift_dispatch_queue_concurrent() -> __OS_dispatch_queue_attr +internal func _swift_dispatch_queue_concurrent() -> dispatch_queue_attr_t @_silgen_name("_swift_dispatch_get_main_queue") -internal func _swift_dispatch_get_main_queue() -> DispatchQueue +internal func _swift_dispatch_get_main_queue() -> dispatch_queue_t @_silgen_name("_swift_dispatch_apply_current_root_queue") -internal func _swift_dispatch_apply_current_root_queue() -> DispatchQueue - -@_silgen_name("_swift_dispatch_async") -internal func _swift_dispatch_async(_ queue: DispatchQueue, _ block: _DispatchBlock) - -@_silgen_name("_swift_dispatch_group_async") -internal func _swift_dispatch_group_async(_ group: DispatchGroup, _ queue: DispatchQueue, _ block: _DispatchBlock) - -@_silgen_name("_swift_dispatch_sync") -internal func _swift_dispatch_sync(_ queue: DispatchQueue, _ block: _DispatchBlock) +internal func _swift_dispatch_apply_current_root_queue() -> dispatch_queue_t @_silgen_name("_swift_dispatch_apply_current") internal func _swift_dispatch_apply_current(_ iterations: Int, _ block: @convention(block) @noescape (Int) -> Void) diff --git a/src/swift/Source.swift b/src/swift/Source.swift index 6ea3960f0..2830f010e 100644 --- a/src/swift/Source.swift +++ b/src/swift/Source.swift @@ -10,51 +10,50 @@ // //===----------------------------------------------------------------------===// -// import Foundation +import CDispatch public extension DispatchSourceType { - typealias DispatchSourceHandler = @convention(block) () -> Void public func setEventHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) { if #available(OSX 10.10, iOS 8.0, *), let h = handler where qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: h) - __dispatch_source_set_event_handler(self as! DispatchSource, item._block) + CDispatch.dispatch_source_set_event_handler((self as! DispatchSource).__wrapped, item._block) } else { - __dispatch_source_set_event_handler(self as! DispatchSource, handler) + CDispatch.dispatch_source_set_event_handler((self as! DispatchSource).__wrapped, handler) } } @available(OSX 10.10, iOS 8.0, *) public func setEventHandler(handler: DispatchWorkItem) { - __dispatch_source_set_event_handler(self as! DispatchSource, handler._block) + CDispatch.dispatch_source_set_event_handler((self as! DispatchSource).__wrapped, handler._block) } public func setCancelHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) { if #available(OSX 10.10, iOS 8.0, *), let h = handler where qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: h) - __dispatch_source_set_cancel_handler(self as! DispatchSource, item._block) + CDispatch.dispatch_source_set_cancel_handler((self as! DispatchSource).__wrapped, item._block) } else { - __dispatch_source_set_cancel_handler(self as! DispatchSource, handler) + CDispatch.dispatch_source_set_cancel_handler((self as! DispatchSource).__wrapped, handler) } } @available(OSX 10.10, iOS 8.0, *) public func setCancelHandler(handler: DispatchWorkItem) { - __dispatch_source_set_cancel_handler(self as! DispatchSource, handler._block) + CDispatch.dispatch_source_set_cancel_handler((self as! DispatchSource).__wrapped, handler._block) } public func setRegistrationHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) { if #available(OSX 10.10, iOS 8.0, *), let h = handler where qos != .unspecified || !flags.isEmpty { let item = DispatchWorkItem(qos: qos, flags: flags, block: h) - __dispatch_source_set_registration_handler(self as! DispatchSource, item._block) + CDispatch.dispatch_source_set_registration_handler((self as! DispatchSource).__wrapped, item._block) } else { - __dispatch_source_set_registration_handler(self as! DispatchSource, handler) + CDispatch.dispatch_source_set_registration_handler((self as! DispatchSource).__wrapped, handler) } } @available(OSX 10.10, iOS 8.0, *) public func setRegistrationHandler(handler: DispatchWorkItem) { - __dispatch_source_set_registration_handler(self as! DispatchSource, handler._block) + CDispatch.dispatch_source_set_registration_handler((self as! DispatchSource).__wrapped, handler._block) } @available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) @@ -63,7 +62,7 @@ public extension DispatchSourceType { } public func cancel() { - __dispatch_source_cancel(self as! DispatchSource) + CDispatch.dispatch_source_cancel((self as! DispatchSource).__wrapped) } public func resume() { @@ -75,30 +74,33 @@ public extension DispatchSourceType { } public var handle: UInt { - return __dispatch_source_get_handle(self as! DispatchSource) + return CDispatch.dispatch_source_get_handle((self as! DispatchSource).__wrapped) } public var mask: UInt { - return __dispatch_source_get_mask(self as! DispatchSource) + return CDispatch.dispatch_source_get_mask((self as! DispatchSource).__wrapped) } public var data: UInt { - return __dispatch_source_get_data(self as! DispatchSource) + return CDispatch.dispatch_source_get_data((self as! DispatchSource).__wrapped) } public var isCancelled: Bool { - return __dispatch_source_testcancel(self as! DispatchSource) != 0 + return CDispatch.dispatch_source_testcancel((self as! DispatchSource).__wrapped) != 0 } } public extension DispatchSource { +#if HAVE_MACH public struct MachSendEvent : OptionSet, RawRepresentable { public let rawValue: UInt public init(rawValue: UInt) { self.rawValue = rawValue } public static let dead = MachSendEvent(rawValue: 0x1) } +#endif +#if HAVE_MACH public struct MemoryPressureEvent : OptionSet, RawRepresentable { public let rawValue: UInt public init(rawValue: UInt) { self.rawValue = rawValue } @@ -108,7 +110,9 @@ public extension DispatchSource { public static let critical = MemoryPressureEvent(rawValue: 0x4) public static let all: MemoryPressureEvent = [.normal, .warning, .critical] } +#endif +#if !os(Linux) public struct ProcessEvent : OptionSet, RawRepresentable { public let rawValue: UInt public init(rawValue: UInt) { self.rawValue = rawValue } @@ -119,6 +123,7 @@ public extension DispatchSource { public static let signal = ProcessEvent(rawValue: 0x08000000) public static let all: ProcessEvent = [.exit, .fork, .exec, .signal] } +#endif public struct TimerFlags : OptionSet, RawRepresentable { public let rawValue: UInt @@ -144,132 +149,153 @@ public extension DispatchSource { .delete, .write, .extend, .attrib, .link, .rename, .revoke] } +#if HAVE_MACH public class func machSend(port: mach_port_t, eventMask: MachSendEvent, queue: DispatchQueue? = nil) -> DispatchSourceMachSend { - return __dispatch_source_create( - _swift_dispatch_source_type_mach_send(), UInt(port), eventMask.rawValue, queue) as DispatchSourceMachSend + let source = dispatch_source_create(_swift_dispatch_source_type_mach_send(), UInt(port), eventMask.rawValue, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceMachSend } +#endif +#if HAVE_MACH public class func machReceive(port: mach_port_t, queue: DispatchQueue? = nil) -> DispatchSourceMachReceive { - return __dispatch_source_create( - _swift_dispatch_source_type_mach_recv(), UInt(port), 0, queue) as DispatchSourceMachReceive + let source = dispatch_source_create(_swift_dispatch_source_type_mach_recv(), UInt(port), 0, queue?.__wrapped) + return DispatchSource(source) as DispatchSourceMachReceive } +#endif +#if HAVE_MACH public class func memoryPressure(eventMask: MemoryPressureEvent, queue: DispatchQueue? = nil) -> DispatchSourceMemoryPressure { - return __dispatch_source_create( - _swift_dispatch_source_type_memorypressure(), 0, eventMask.rawValue, queue) as DispatchSourceMemoryPressure + let source = dispatch_source_create(_swift_dispatch_source_type_memorypressure(), 0, eventMask.rawValue, queue.__wrapped) + return DispatchSourceMemoryPressure(source) } +#endif +#if !os(Linux) public class func process(identifier: pid_t, eventMask: ProcessEvent, queue: DispatchQueue? = nil) -> DispatchSourceProcess { - return __dispatch_source_create( - _swift_dispatch_source_type_proc(), UInt(identifier), eventMask.rawValue, queue) as DispatchSourceProcess + let source = dispatch_source_create(_swift_dispatch_source_type_proc(), UInt(identifier), eventMask.rawValue, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceProcess } +#endif public class func read(fileDescriptor: Int32, queue: DispatchQueue? = nil) -> DispatchSourceRead { - return __dispatch_source_create( - _swift_dispatch_source_type_read(), UInt(fileDescriptor), 0, queue) as DispatchSourceRead + let source = dispatch_source_create(_swift_dispatch_source_type_read(), UInt(fileDescriptor), 0, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceRead } public class func signal(signal: Int32, queue: DispatchQueue? = nil) -> DispatchSourceSignal { - return __dispatch_source_create( - _swift_dispatch_source_type_read(), UInt(signal), 0, queue) as DispatchSourceSignal + let source = dispatch_source_create(_swift_dispatch_source_type_signal(), UInt(signal), 0, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceSignal } public class func timer(flags: TimerFlags = [], queue: DispatchQueue? = nil) -> DispatchSourceTimer { - return __dispatch_source_create(_swift_dispatch_source_type_timer(), 0, flags.rawValue, queue) as DispatchSourceTimer + let source = dispatch_source_create(_swift_dispatch_source_type_timer(), 0, flags.rawValue, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceTimer } public class func userDataAdd(queue: DispatchQueue? = nil) -> DispatchSourceUserDataAdd { - return __dispatch_source_create(_swift_dispatch_source_type_data_add(), 0, 0, queue) as DispatchSourceUserDataAdd + let source = dispatch_source_create(_swift_dispatch_source_type_data_add(), 0, 0, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceUserDataAdd } public class func userDataOr(queue: DispatchQueue? = nil) -> DispatchSourceUserDataOr { - return __dispatch_source_create(_swift_dispatch_source_type_data_or(), 0, 0, queue) as DispatchSourceUserDataOr + let source = dispatch_source_create(_swift_dispatch_source_type_data_or(), 0, 0, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceUserDataOr } +#if !os(Linux) public class func fileSystemObject(fileDescriptor: Int32, eventMask: FileSystemEvent, queue: DispatchQueue? = nil) -> DispatchSourceFileSystemObject { - return __dispatch_source_create( - _swift_dispatch_source_type_vnode(), UInt(fileDescriptor), eventMask.rawValue, queue) as DispatchSourceFileSystemObject + let source = dispatch_source_create(_swift_dispatch_source_type_vnode(), UInt(fileDescriptor), eventMask.rawValue, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceFileSystemObject } +#endif public class func write(fileDescriptor: Int32, queue: DispatchQueue? = nil) -> DispatchSourceWrite { - return __dispatch_source_create( - _swift_dispatch_source_type_write(), UInt(fileDescriptor), 0, queue) as DispatchSourceWrite + let source = dispatch_source_create(_swift_dispatch_source_type_write(), UInt(fileDescriptor), 0, queue?.__wrapped) + return DispatchSource(source: source) as DispatchSourceWrite } } +#if HAVE_MACH public extension DispatchSourceMachSend { public var handle: mach_port_t { - return mach_port_t(__dispatch_source_get_handle(self as! DispatchSource)) + return mach_port_t(dispatch_source_get_handle(self as! DispatchSource)) } public var data: DispatchSource.MachSendEvent { - let data = __dispatch_source_get_data(self as! DispatchSource) + let data = dispatch_source_get_data(self as! DispatchSource) return DispatchSource.MachSendEvent(rawValue: data) } public var mask: DispatchSource.MachSendEvent { - let mask = __dispatch_source_get_mask(self as! DispatchSource) + let mask = dispatch_source_get_mask(self as! DispatchSource) return DispatchSource.MachSendEvent(rawValue: mask) } } +#endif +#if HAVE_MACH public extension DispatchSourceMachReceive { public var handle: mach_port_t { - return mach_port_t(__dispatch_source_get_handle(self as! DispatchSource)) + return mach_port_t(dispatch_source_get_handle(self as! DispatchSource)) } } +#endif +#if HAVE_MACH public extension DispatchSourceMemoryPressure { public var data: DispatchSource.MemoryPressureEvent { - let data = __dispatch_source_get_data(self as! DispatchSource) + let data = dispatch_source_get_data(self as! DispatchSource) return DispatchSource.MemoryPressureEvent(rawValue: data) } public var mask: DispatchSource.MemoryPressureEvent { - let mask = __dispatch_source_get_mask(self as! DispatchSource) + let mask = dispatch_source_get_mask(self as! DispatchSource) return DispatchSource.MemoryPressureEvent(rawValue: mask) } } +#endif +#if !os(Linux) public extension DispatchSourceProcess { public var handle: pid_t { - return pid_t(__dispatch_source_get_handle(self as! DispatchSource)) + return pid_t(dispatch_source_get_handle(self as! DispatchSource)) } public var data: DispatchSource.ProcessEvent { - let data = __dispatch_source_get_data(self as! DispatchSource) + let data = dispatch_source_get_data(self as! DispatchSource) return DispatchSource.ProcessEvent(rawValue: data) } public var mask: DispatchSource.ProcessEvent { - let mask = __dispatch_source_get_mask(self as! DispatchSource) + let mask = dispatch_source_get_mask(self as! DispatchSource) return DispatchSource.ProcessEvent(rawValue: mask) } } +#endif public extension DispatchSourceTimer { public func scheduleOneshot(deadline: DispatchTime, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, ~0, UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, deadline.rawValue, ~0, UInt64(leeway.rawValue)) } public func scheduleOneshot(wallDeadline: DispatchWallTime, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, ~0, UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, wallDeadline.rawValue, ~0, UInt64(leeway.rawValue)) } public func scheduleRepeating(deadline: DispatchTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, interval.rawValue, UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, deadline.rawValue, interval.rawValue, UInt64(leeway.rawValue)) } public func scheduleRepeating(deadline: DispatchTime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, UInt64(interval * Double(NSEC_PER_SEC)), UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, deadline.rawValue, UInt64(interval * Double(NSEC_PER_SEC)), UInt64(leeway.rawValue)) } public func scheduleRepeating(wallDeadline: DispatchWallTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, interval.rawValue, UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, wallDeadline.rawValue, interval.rawValue, UInt64(leeway.rawValue)) } public func scheduleRepeating(wallDeadline: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) { - __dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, UInt64(interval * Double(NSEC_PER_SEC)), UInt64(leeway.rawValue)) + dispatch_source_set_timer((self as! DispatchSource).__wrapped, wallDeadline.rawValue, UInt64(interval * Double(NSEC_PER_SEC)), UInt64(leeway.rawValue)) } } @@ -300,26 +326,28 @@ public extension DispatchSourceTimer { } @available(*, deprecated, renamed: "DispatchSourceTimer.scheduleRepeating(self:wallDeadline:interval:leeway:)") - public func setTimer(walltime start: DispatchWalltime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) { + public func setTimer(walltime start: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) { scheduleRepeating(wallDeadline: start, interval: interval, leeway: leeway) } } +#if !os(Linux) public extension DispatchSourceFileSystemObject { public var handle: Int32 { - return Int32(__dispatch_source_get_handle(self as! DispatchSource)) + return Int32(dispatch_source_get_handle((self as! DispatchSource).__wrapped)) } public var data: DispatchSource.FileSystemEvent { - let data = __dispatch_source_get_data(self as! DispatchSource) + let data = dispatch_source_get_data((self as! DispatchSource).__wrapped) return DispatchSource.FileSystemEvent(rawValue: data) } public var mask: DispatchSource.FileSystemEvent { - let data = __dispatch_source_get_mask(self as! DispatchSource) + let data = dispatch_source_get_mask((self as! DispatchSource).__wrapped) return DispatchSource.FileSystemEvent(rawValue: data) } } +#endif public extension DispatchSourceUserDataAdd { /// @function mergeData @@ -334,11 +362,12 @@ public extension DispatchSourceUserDataAdd { /// as specified by the dispatch source type. A value of zero has no effect /// and will not result in the submission of the event handler block. public func mergeData(value: UInt) { - __dispatch_source_merge_data(self as! DispatchSource, value) + dispatch_source_merge_data((self as! DispatchSource).__wrapped, value) } } public extension DispatchSourceUserDataOr { +#if false /*FIXME: clashes with UserDataAdd?? */ /// @function mergeData /// /// @abstract @@ -351,39 +380,46 @@ public extension DispatchSourceUserDataOr { /// as specified by the dispatch source type. A value of zero has no effect /// and will not result in the submission of the event handler block. public func mergeData(value: UInt) { - __dispatch_source_merge_data(self as! DispatchSource, value) + dispatch_source_merge_data((self as! DispatchSource).__wrapped, value) } +#endif } @_silgen_name("_swift_dispatch_source_type_DATA_ADD") -internal func _swift_dispatch_source_type_data_add() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_data_add() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_DATA_OR") -internal func _swift_dispatch_source_type_data_or() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_data_or() -> dispatch_source_type_t +#if HAVE_MACH @_silgen_name("_swift_dispatch_source_type_MACH_SEND") -internal func _swift_dispatch_source_type_mach_send() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_mach_send() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_MACH_RECV") -internal func _swift_dispatch_source_type_mach_recv() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_mach_recv() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_MEMORYPRESSURE") -internal func _swift_dispatch_source_type_memorypressure() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_memorypressure() -> dispatch_source_type_t +#endif +#if !os(Linux) @_silgen_name("_swift_dispatch_source_type_PROC") -internal func _swift_dispatch_source_type_proc() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_proc() -> dispatch_source_type_t +#endif @_silgen_name("_swift_dispatch_source_type_READ") -internal func _swift_dispatch_source_type_read() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_read() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_SIGNAL") -internal func _swift_dispatch_source_type_signal() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_signal() -> dispatch_source_type_t @_silgen_name("_swift_dispatch_source_type_TIMER") -internal func _swift_dispatch_source_type_timer() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_timer() -> dispatch_source_type_t +#if !os(Linux) @_silgen_name("_swift_dispatch_source_type_VNODE") -internal func _swift_dispatch_source_type_vnode() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_vnode() -> dispatch_source_type_t +#endif @_silgen_name("_swift_dispatch_source_type_WRITE") -internal func _swift_dispatch_source_type_write() -> __dispatch_source_type_t +internal func _swift_dispatch_source_type_write() -> dispatch_source_type_t diff --git a/src/swift/Time.swift b/src/swift/Time.swift index e0b63b814..76a6979eb 100644 --- a/src/swift/Time.swift +++ b/src/swift/Time.swift @@ -14,11 +14,13 @@ // DISPATCH_TIME_NOW: ok // DISPATCH_TIME_FOREVER: ok +import CDispatch + public struct DispatchTime { public let rawValue: dispatch_time_t public static func now() -> DispatchTime { - let t = __dispatch_time(0, 0) + let t = CDispatch.dispatch_time(0, 0) return DispatchTime(rawValue: t) } @@ -33,7 +35,7 @@ public struct DispatchWallTime { public let rawValue: dispatch_time_t public static func now() -> DispatchWallTime { - return DispatchWallTime(rawValue: __dispatch_walltime(nil, 0)) + return DispatchWallTime(rawValue: CDispatch.dispatch_walltime(nil, 0)) } public static let distantFuture = DispatchWallTime(rawValue: ~0) @@ -44,7 +46,7 @@ public struct DispatchWallTime { public init(time: timespec) { var t = time - self.rawValue = __dispatch_walltime(&t, 0) + self.rawValue = CDispatch.dispatch_walltime(&t, 0) } } @@ -68,41 +70,41 @@ public enum DispatchTimeInterval { } public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime { - let t = __dispatch_time(time.rawValue, Int64(interval.rawValue)) + let t = CDispatch.dispatch_time(time.rawValue, Int64(interval.rawValue)) return DispatchTime(rawValue: t) } public func -(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime { - let t = __dispatch_time(time.rawValue, -Int64(interval.rawValue)) + let t = CDispatch.dispatch_time(time.rawValue, -Int64(interval.rawValue)) return DispatchTime(rawValue: t) } public func +(time: DispatchTime, seconds: Double) -> DispatchTime { - let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC))) + let t = CDispatch.dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC))) return DispatchTime(rawValue: t) } public func -(time: DispatchTime, seconds: Double) -> DispatchTime { - let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC))) + let t = CDispatch.dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC))) return DispatchTime(rawValue: t) } public func +(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime { - let t = __dispatch_time(time.rawValue, Int64(interval.rawValue)) + let t = CDispatch.dispatch_time(time.rawValue, Int64(interval.rawValue)) return DispatchWallTime(rawValue: t) } public func -(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime { - let t = __dispatch_time(time.rawValue, -Int64(interval.rawValue)) + let t = CDispatch.dispatch_time(time.rawValue, -Int64(interval.rawValue)) return DispatchWallTime(rawValue: t) } public func +(time: DispatchWallTime, seconds: Double) -> DispatchWallTime { - let t = __dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC))) + let t = CDispatch.dispatch_time(time.rawValue, Int64(seconds * Double(NSEC_PER_SEC))) return DispatchWallTime(rawValue: t) } public func -(time: DispatchWallTime, seconds: Double) -> DispatchWallTime { - let t = __dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC))) + let t = CDispatch.dispatch_time(time.rawValue, Int64(-seconds * Double(NSEC_PER_SEC))) return DispatchWallTime(rawValue: t) } diff --git a/src/swift/Wrapper.swift b/src/swift/Wrapper.swift new file mode 100644 index 000000000..a0d1e8e4f --- /dev/null +++ b/src/swift/Wrapper.swift @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import CDispatch + +// This file contains declarations that are provided by the +// importer via Dispatch.apinote when the platform has Objective-C support + +public class DispatchObject { + // TODO: add deinit method to invoke dispatch_release on wrapped() + + internal func wrapped() -> dispatch_object_t { + assert(false, "should be override in subclass") + } + + public func setTarget(queue:DispatchQueue) { + dispatch_set_target_queue(wrapped(), queue.__wrapped) + } + + public func activate() { + dispatch_activate(wrapped()) + } + + public func suspend() { + dispatch_suspend(wrapped()) + } + + public func resume() { + dispatch_resume(wrapped()) + } +} + + +public class DispatchGroup : DispatchObject { + internal let __wrapped:dispatch_group_t; + + internal override func wrapped() -> dispatch_object_t { + return unsafeBitCast(__wrapped, to: dispatch_object_t.self) + } + + public override init() { + __wrapped = dispatch_group_create() + } + + public func enter() { + dispatch_group_enter(__wrapped) + } + + public func leave() { + dispatch_group_enter(__wrapped) + } +} + +public class DispatchSemaphore : DispatchObject { + internal let __wrapped: dispatch_semaphore_t; + + internal override func wrapped() -> dispatch_object_t { + return unsafeBitCast(__wrapped, to: dispatch_object_t.self) + } + + public init(value: Int) { + __wrapped = dispatch_semaphore_create(value) + } +} + +public class DispatchIO : DispatchObject { + internal let __wrapped:dispatch_io_t + + internal override func wrapped() -> dispatch_object_t { + return unsafeBitCast(__wrapped, to: dispatch_object_t.self) + } + + internal init(__type: UInt, fd: Int32, queue: DispatchQueue, + handler: (error: Int32) -> Void) { + __wrapped = dispatch_io_create(__type, fd, queue.__wrapped, handler) + } + + internal init(__type: UInt, path: UnsafePointer, oflag: Int32, + mode: mode_t, queue: DispatchQueue, handler: (error: Int32) -> Void) { + __wrapped = dispatch_io_create_with_path(__type, path, oflag, mode, queue.__wrapped, handler) + } + + internal init(__type: UInt, io: DispatchIO, + queue: DispatchQueue, handler: (error: Int32) -> Void) { + __wrapped = dispatch_io_create_with_io(__type, io.__wrapped, queue.__wrapped, handler) + } + + internal init(queue:dispatch_queue_t) { + __wrapped = queue + } + + public func barrier(execute: () -> ()) { + dispatch_io_barrier(self.__wrapped, execute) + } + + public var fileDescriptor: Int32 { + return dispatch_io_get_descriptor(__wrapped) + } + + public func setLimit(highWater: Int) { + dispatch_io_set_high_water(__wrapped, highWater) + } + + public func setLimit(lowWater: Int) { + dispatch_io_set_low_water(__wrapped, lowWater) + } +} + +public class DispatchQueue : DispatchObject { + internal let __wrapped:dispatch_queue_t; + + internal override func wrapped() -> dispatch_object_t { + return unsafeBitCast(__wrapped, to: dispatch_object_t.self) + } + + internal init(__label: String, attr: dispatch_queue_attr_t?) { + __wrapped = dispatch_queue_create(__label, attr) + } + + internal init(__label: String, attr: dispatch_queue_attr_t?, queue: DispatchQueue?) { + __wrapped = dispatch_queue_create_with_target(__label, attr, queue?.__wrapped) + } + + internal init(queue:dispatch_queue_t) { + __wrapped = queue + } + + public func sync(execute workItem: @noescape ()->()) { + dispatch_sync(self.__wrapped, workItem) + } +} + +public class DispatchSource : DispatchObject, + DispatchSourceType, DispatchSourceRead, + DispatchSourceSignal, DispatchSourceTimer, + DispatchSourceUserDataAdd, DispatchSourceUserDataOr, + DispatchSourceWrite { + internal let __wrapped:dispatch_source_t + + internal override func wrapped() -> dispatch_object_t { + return unsafeBitCast(__wrapped, to: dispatch_object_t.self) + } + + internal init(source:dispatch_source_t) { + __wrapped = source + } +} + +#if HAVE_MACH +extension DispatchSource : DispatchSourceMachSend, + DispatchSourceMachReceive, DispatchSourceMemoryPressure { +} +#endif + +#if !os(Linux) +extension DispatchSource : DispatchSourceProcess, + DispatchSourceFileSystemObject { +} +#endif + +public typealias DispatchSourceHandler = @convention(block) () -> Void + +public protocol DispatchSourceType { + func setEventHandler(qos: DispatchQoS, flags: DispatchWorkItemFlags, handler: DispatchSourceHandler?) + + func setEventHandler(handler: DispatchWorkItem) + + func setCancelHandler(qos: DispatchQoS, flags: DispatchWorkItemFlags, handler: DispatchSourceHandler?) + + func setCancelHandler(handler: DispatchWorkItem) + + func setRegistrationHandler(qos: DispatchQoS, flags: DispatchWorkItemFlags, handler: DispatchSourceHandler?) + + func setRegistrationHandler(handler: DispatchWorkItem) + + func cancel() + + func resume() + + func suspend() + + var handle: UInt { get } + + var mask: UInt { get } + + var data: UInt { get } + + var isCancelled: Bool { get } +} + +public protocol DispatchSourceUserDataAdd : DispatchSourceType { + func mergeData(value: UInt) +} + +public protocol DispatchSourceUserDataOr { +#if false /*FIXME: clashes with UserDataAdd?? */ + func mergeData(value: UInt) +#endif +} + +#if HAVE_MACH +public protocol DispatchSourceMachSend : DispatchSourceType { + public var handle: mach_port_t { get } + + public var data: DispatchSource.MachSendEvent { get } + + public var mask: DispatchSource.MachSendEvent { get } +} +#endif + +#if HAVE_MACH +public protocol DispatchSourceMachReceive : DispatchSourceType { + var handle: mach_port_t { get } +} +#endif + +#if HAVE_MACH +public protocol DispatchSourceMemoryPressure : DispatchSourceType { + public var data: DispatchSource.MemoryPressureEvent { get } + + public var mask: DispatchSource.MemoryPressureEvent { get } +} +#endif + +#if !os(Linux) +public protocol DispatchSourceProcess : DispatchSourceType { + var handle: pid_t { get } + + var data: DispatchSource.ProcessEvent { get } + + var mask: DispatchSource.ProcessEvent { get } +} +#endif + +public protocol DispatchSourceRead : DispatchSourceType { +} + +public protocol DispatchSourceSignal : DispatchSourceType { +} + +public protocol DispatchSourceTimer : DispatchSourceType { + func setTimer(start: DispatchTime, leeway: DispatchTimeInterval) + + func setTimer(walltime start: DispatchWallTime, leeway: DispatchTimeInterval) + + func setTimer(start: DispatchTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval) + + func setTimer(start: DispatchTime, interval: Double, leeway: DispatchTimeInterval) + + func setTimer(walltime start: DispatchWallTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval) + + func setTimer(walltime start: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval) +} + +#if !os(Linux) +public protocol DispatchSourceFileSystemObject : DispatchSourceType { + var handle: Int32 { get } + + var data: DispatchSource.FileSystemEvent { get } + + var mask: DispatchSource.FileSystemEvent { get } +} +#endif + +public protocol DispatchSourceWrite : DispatchSourceType { +} + + +internal enum _OSQoSClass : UInt32 { + case QOS_CLASS_USER_INTERACTIVE = 0x21 + case QOS_CLASS_USER_INITIATED = 0x19 + case QOS_CLASS_DEFAULT = 0x15 + case QOS_CLASS_UTILITY = 0x11 + case QOS_CLASS_BACKGROUND = 0x09 + case QOS_CLASS_UNSPECIFIED = 0x00 + + internal init?(qosClass:dispatch_qos_class_t) { + switch qosClass { + case 0x21: self = .QOS_CLASS_USER_INTERACTIVE + case 0x19: self = .QOS_CLASS_USER_INITIATED + case 0x15: self = .QOS_CLASS_DEFAULT + case 0x11: self = QOS_CLASS_UTILITY + case 0x09: self = QOS_CLASS_BACKGROUND + case 0x00: self = QOS_CLASS_UNSPECIFIED + default: return nil + } + } +} diff --git a/tests/Makefile.am b/tests/Makefile.am index fa37f8a00..c7776e468 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -121,7 +121,11 @@ if HAVE_PTHREAD_WORKQUEUES endif endif -LDADD=libbsdtests.la $(top_builddir)/src/libdispatch.la $(KQUEUE_LIBS) $(PTHREAD_WORKQUEUE_LIBS) $(BSD_OVERLAY_LIBS) +if HAVE_SWIFT + SWIFT_LIBS=-L$(SWIFT_LIBDIR) -lswiftCore +endif + +LDADD=libbsdtests.la $(top_builddir)/src/libdispatch.la $(KQUEUE_LIBS) $(PTHREAD_WORKQUEUE_LIBS) $(BSD_OVERLAY_LIBS) $(SWIFT_LIBS) libbsdtests_la_LDFLAGS=-avoid-version bsdtestsummarize_LDADD=-lm $(BSD_OVERLAY_LIBS)