Skip to content

Commit

Permalink
RxSwift compiles first time on Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
kzaher committed Dec 26, 2015
1 parent 4651df2 commit a982be0
Show file tree
Hide file tree
Showing 16 changed files with 450 additions and 174 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Expand Up @@ -49,4 +49,4 @@ Carthage/Build
# Swift Package Manager # Swift Package Manager


.build/ .build/

Packages/
1 change: 0 additions & 1 deletion Package.swift
Expand Up @@ -30,7 +30,6 @@ let package = Package(
dependencies: [ dependencies: [
.Target(name: "RxSwift"), .Target(name: "RxSwift"),
.Target(name: "RxBlocking"), .Target(name: "RxBlocking"),
.Target(name: "RxCocoa"),
.Target(name: "RxTests") .Target(name: "RxTests")
] ]
) )
Expand Down
131 changes: 91 additions & 40 deletions RxSwift/Concurrency/Lock.swift
Expand Up @@ -13,61 +13,112 @@ protocol Lock {
func unlock() func unlock()
} }


/** #if os(Linux)
Simple wrapper for spin lock. import Glibc
*/
struct SpinLock {
private var _lock = OS_SPINLOCK_INIT

init() {

}


mutating func lock() { /**
OSSpinLockLock(&_lock) Simple wrapper for spin lock.
} */
class SpinLock {
private var _lock: pthread_spinlock_t = 0


mutating func unlock() { init() {
OSSpinLockUnlock(&_lock) if (pthread_spin_init(&_lock, 0) != 0) {
} fatalError("Spin lock initialization failed")

}
mutating func performLocked(@noescape action: () -> Void) { }
OSSpinLockLock(&_lock)
action()
OSSpinLockUnlock(&_lock)
}

mutating func calculateLocked<T>(@noescape action: () -> T) -> T {
OSSpinLockLock(&_lock)
let result = action()
OSSpinLockUnlock(&_lock)
return result
}


mutating func calculateLockedOrFail<T>(@noescape action: () throws -> T) throws -> T { func lock() {
OSSpinLockLock(&_lock) pthread_spin_lock(&_lock)
defer { }
OSSpinLockUnlock(&_lock)
} func unlock() {
let result = try action() pthread_spin_unlock(&_lock)
return result }
}
} func performLocked(@noescape action: () -> Void) {
pthread_spin_lock(&_lock)
action()
pthread_spin_unlock(&_lock)
}

func calculateLocked<T>(@noescape action: () -> T) -> T {
pthread_spin_lock(&_lock)
let result = action()
pthread_spin_unlock(&_lock)
return result
}

func calculateLockedOrFail<T>(@noescape action: () throws -> T) throws -> T {
pthread_spin_lock(&_lock)
defer {
pthread_spin_unlock(&_lock)
}
let result = try action()
return result
}

deinit {
pthread_spin_destroy(&_lock)
}
}
#else
/**
Simple wrapper for spin lock.
*/
struct SpinLock {
private var _lock = OS_SPINLOCK_INIT

init() {

}

mutating func lock() {
OSSpinLockLock(&_lock)
}

mutating func unlock() {
OSSpinLockUnlock(&_lock)
}

mutating func performLocked(@noescape action: () -> Void) {
OSSpinLockLock(&_lock)
action()
OSSpinLockUnlock(&_lock)
}

mutating func calculateLocked<T>(@noescape action: () -> T) -> T {
OSSpinLockLock(&_lock)
let result = action()
OSSpinLockUnlock(&_lock)
return result
}

mutating func calculateLockedOrFail<T>(@noescape action: () throws -> T) throws -> T {
OSSpinLockLock(&_lock)
defer {
OSSpinLockUnlock(&_lock)
}
let result = try action()
return result
}
}
#endif


extension NSRecursiveLock : Lock { extension NSRecursiveLock : Lock {
func performLocked(@noescape action: () -> Void) { func performLocked(@noescape action: () -> Void) {
self.lock() self.lock()
action() action()
self.unlock() self.unlock()
} }

func calculateLocked<T>(@noescape action: () -> T) -> T { func calculateLocked<T>(@noescape action: () -> T) -> T {
self.lock() self.lock()
let result = action() let result = action()
self.unlock() self.unlock()
return result return result
} }

func calculateLockedOrFail<T>(@noescape action: () throws -> T) throws -> T { func calculateLockedOrFail<T>(@noescape action: () throws -> T) throws -> T {
self.lock() self.lock()
defer { defer {
Expand Down Expand Up @@ -102,4 +153,4 @@ extension pthread_mutex_t {
pthread_mutex_unlock(&self) pthread_mutex_unlock(&self)
} }
} }
*/ */
16 changes: 8 additions & 8 deletions RxSwift/Disposables/AnonymousDisposable.swift
Expand Up @@ -15,10 +15,10 @@ When dispose method is called, disposal action will be dereferenced.
*/ */
public final class AnonymousDisposable : DisposeBase, Cancelable { public final class AnonymousDisposable : DisposeBase, Cancelable {
public typealias DisposeAction = () -> Void public typealias DisposeAction = () -> Void

private var _disposed: Int32 = 0 private var _disposed: AtomicInt = 0
private var _disposeAction: DisposeAction? private var _disposeAction: DisposeAction?

/** /**
- returns: Was resource disposed. - returns: Was resource disposed.
*/ */
Expand All @@ -27,10 +27,10 @@ public final class AnonymousDisposable : DisposeBase, Cancelable {
return _disposed == 1 return _disposed == 1
} }
} }

/** /**
Constructs a new disposable with the given action used for disposal. Constructs a new disposable with the given action used for disposal.
- parameter disposeAction: Disposal action which will be run upon calling `dispose`. - parameter disposeAction: Disposal action which will be run upon calling `dispose`.
*/ */
public init(_ disposeAction: DisposeAction) { public init(_ disposeAction: DisposeAction) {
Expand All @@ -40,11 +40,11 @@ public final class AnonymousDisposable : DisposeBase, Cancelable {


/** /**
Calls the disposal action if and only if the current instance hasn't been disposed yet. Calls the disposal action if and only if the current instance hasn't been disposed yet.
After invoking disposal action, disposal action will be dereferenced. After invoking disposal action, disposal action will be dereferenced.
*/ */
public func dispose() { public func dispose() {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) { if AtomicCompareAndSwap(0, 1, &_disposed) {
assert(_disposed == 1) assert(_disposed == 1)


if let action = _disposeAction { if let action = _disposeAction {
Expand All @@ -53,4 +53,4 @@ public final class AnonymousDisposable : DisposeBase, Cancelable {
} }
} }
} }
} }
18 changes: 9 additions & 9 deletions RxSwift/Disposables/BinaryDisposable.swift
Expand Up @@ -12,13 +12,13 @@ import Foundation
Represents two disposable resources that are disposed together. Represents two disposable resources that are disposed together.
*/ */
public final class BinaryDisposable : DisposeBase, Cancelable { public final class BinaryDisposable : DisposeBase, Cancelable {

private var _disposed: Int32 = 0 private var _disposed: AtomicInt = 0


// state // state
private var _disposable1: Disposable? private var _disposable1: Disposable?
private var _disposable2: Disposable? private var _disposable2: Disposable?

/** /**
- returns: Was resource disposed. - returns: Was resource disposed.
*/ */
Expand All @@ -27,10 +27,10 @@ public final class BinaryDisposable : DisposeBase, Cancelable {
return _disposed > 0 return _disposed > 0
} }
} }

/** /**
Constructs new binary disposable from two disposables. Constructs new binary disposable from two disposables.
- parameter disposable1: First disposable - parameter disposable1: First disposable
- parameter disposable2: Second disposable - parameter disposable2: Second disposable
*/ */
Expand All @@ -39,18 +39,18 @@ public final class BinaryDisposable : DisposeBase, Cancelable {
_disposable2 = disposable2 _disposable2 = disposable2
super.init() super.init()
} }

/** /**
Calls the disposal action if and only if the current instance hasn't been disposed yet. Calls the disposal action if and only if the current instance hasn't been disposed yet.
After invoking disposal action, disposal action will be dereferenced. After invoking disposal action, disposal action will be dereferenced.
*/ */
public func dispose() { public func dispose() {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) { if AtomicCompareAndSwap(0, 1, &_disposed) {
_disposable1?.dispose() _disposable1?.dispose()
_disposable2?.dispose() _disposable2?.dispose()
_disposable1 = nil _disposable1 = nil
_disposable2 = nil _disposable2 = nil
} }
} }
} }
38 changes: 19 additions & 19 deletions RxSwift/Disposables/RefCountDisposable.swift
Expand Up @@ -16,7 +16,7 @@ public class RefCountDisposable : DisposeBase, Cancelable {
private var _disposable = nil as Disposable? private var _disposable = nil as Disposable?
private var _primaryDisposed = false private var _primaryDisposed = false
private var _count = 0 private var _count = 0

/** /**
- returns: Was resource disposed. - returns: Was resource disposed.
*/ */
Expand All @@ -26,24 +26,24 @@ public class RefCountDisposable : DisposeBase, Cancelable {
return _disposable == nil return _disposable == nil
} }
} }

/** /**
Initializes a new instance of the `RefCountDisposable`. Initializes a new instance of the `RefCountDisposable`.
*/ */
public init(disposable: Disposable) { public init(disposable: Disposable) {
_disposable = disposable _disposable = disposable
super.init() super.init()
} }

/** /**
Holds a dependent disposable that when disposed decreases the refcount on the underlying disposable. Holds a dependent disposable that when disposed decreases the refcount on the underlying disposable.
When getter is called, a dependent disposable contributing to the reference count that manages the underlying disposable's lifetime is returned. When getter is called, a dependent disposable contributing to the reference count that manages the underlying disposable's lifetime is returned.
*/ */
public func retain() -> Disposable { public func retain() -> Disposable {
return _lock.calculateLocked { return _lock.calculateLocked {
if let _ = _disposable { if let _ = _disposable {

do { do {
try incrementChecked(&_count) try incrementChecked(&_count)
} catch (_) { } catch (_) {
Expand All @@ -56,7 +56,7 @@ public class RefCountDisposable : DisposeBase, Cancelable {
} }
} }
} }

/** /**
Disposes the underlying disposable only when all dependent disposables have been disposed. Disposes the underlying disposable only when all dependent disposables have been disposed.
*/ */
Expand All @@ -65,22 +65,22 @@ public class RefCountDisposable : DisposeBase, Cancelable {
if let oldDisposable = _disposable where !_primaryDisposed if let oldDisposable = _disposable where !_primaryDisposed
{ {
_primaryDisposed = true _primaryDisposed = true

if (_count == 0) if (_count == 0)
{ {
_disposable = nil _disposable = nil
return oldDisposable return oldDisposable
} }
} }

return nil return nil
} }

if let disposable = oldDisposable { if let disposable = oldDisposable {
disposable.dispose() disposable.dispose()
} }
} }

private func release() { private func release() {
let oldDisposable: Disposable? = _lock.calculateLocked { let oldDisposable: Disposable? = _lock.calculateLocked {
if let oldDisposable = _disposable { if let oldDisposable = _disposable {
Expand All @@ -89,20 +89,20 @@ public class RefCountDisposable : DisposeBase, Cancelable {
} catch (_) { } catch (_) {
rxFatalError("RefCountDisposable decrement on release failed") rxFatalError("RefCountDisposable decrement on release failed")
} }

guard _count >= 0 else { guard _count >= 0 else {
rxFatalError("RefCountDisposable counter is lower than 0") rxFatalError("RefCountDisposable counter is lower than 0")
} }

if _primaryDisposed && _count == 0 { if _primaryDisposed && _count == 0 {
_disposable = nil _disposable = nil
return oldDisposable return oldDisposable
} }
} }

return nil return nil
} }

if let disposable = oldDisposable { if let disposable = oldDisposable {
disposable.dispose() disposable.dispose()
} }
Expand All @@ -112,18 +112,18 @@ public class RefCountDisposable : DisposeBase, Cancelable {
internal final class RefCountInnerDisposable: DisposeBase, Disposable internal final class RefCountInnerDisposable: DisposeBase, Disposable
{ {
private let _parent: RefCountDisposable private let _parent: RefCountDisposable
private var _disposed: Int32 = 0 private var _disposed: AtomicInt = 0

init(_ parent: RefCountDisposable) init(_ parent: RefCountDisposable)
{ {
_parent = parent _parent = parent
super.init() super.init()
} }

internal func dispose() internal func dispose()
{ {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) { if AtomicCompareAndSwap(0, 1, &_disposed) {
_parent.release() _parent.release()
} }
} }
} }

0 comments on commit a982be0

Please sign in to comment.