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
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ Carthage/Build
# Swift Package Manager

.build/

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

/**
Simple wrapper for spin lock.
*/
struct SpinLock {
private var _lock = OS_SPINLOCK_INIT

init() {

}
#if os(Linux)
import Glibc

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

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
}
init() {
if (pthread_spin_init(&_lock, 0) != 0) {
fatalError("Spin lock initialization failed")
}
}

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

func unlock() {
pthread_spin_unlock(&_lock)
}

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 {
func performLocked(@noescape action: () -> Void) {
self.lock()
action()
self.unlock()
}

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

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

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

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

/**
Constructs a new disposable with the given action used for disposal.
- parameter disposeAction: Disposal action which will be run upon calling `dispose`.
*/
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.
After invoking disposal action, disposal action will be dereferenced.
*/
public func dispose() {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) {
if AtomicCompareAndSwap(0, 1, &_disposed) {
assert(_disposed == 1)

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
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import Foundation
Represents two disposable resources that are disposed together.
*/
public final class BinaryDisposable : DisposeBase, Cancelable {
private var _disposed: Int32 = 0

private var _disposed: AtomicInt = 0

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

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

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

/**
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.
*/
public func dispose() {
if OSAtomicCompareAndSwap32(0, 1, &_disposed) {
if AtomicCompareAndSwap(0, 1, &_disposed) {
_disposable1?.dispose()
_disposable2?.dispose()
_disposable1 = nil
_disposable2 = nil
}
}
}
}
38 changes: 19 additions & 19 deletions RxSwift/Disposables/RefCountDisposable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class RefCountDisposable : DisposeBase, Cancelable {
private var _disposable = nil as Disposable?
private var _primaryDisposed = false
private var _count = 0

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

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

/**
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.
*/
public func retain() -> Disposable {
return _lock.calculateLocked {
if let _ = _disposable {

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

/**
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
{
_primaryDisposed = true

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

return nil
}

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

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

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

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

return nil
}

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

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

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

0 comments on commit a982be0

Please sign in to comment.