In my swift practice, I wrote simple struct named `OrderedSet`.

I tried `OrderedSet` to be a thread-safe with GCD serial queue.

But it’s not working. The test result is unstable. I expected something like:

```
20:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

```

but received something like like 

```
2:[3, 19]

```

here is playground code:

```
import Foundation
import XCPlayground

struct OrderedSet<T: Equatable> {
    mutating func append(e: T) {
        dispatch_sync(q) {
            if !self.__elements.contains(e) {
                self.__elements.append(e)
            }
        }
    }
    var elements: [T] {
        var elements: [T] = []
        dispatch_sync(q) {
            elements = self.__elements
        }
        return elements
    }
    var count: Int {
        var ret = 0
        dispatch_sync(q) {
            ret = self.__elements.count
        }
        return ret
    }
    private var __elements: [T] = []
    private let q = dispatch_queue_create("OrderedSet.private.serial.queue", DISPATCH_QUEUE_SERIAL)
}
extension OrderedSet: CustomStringConvertible {
    var description: String {
        var text = ""
        dispatch_sync(q) {
            text = "\(self.__elements.count):\(self.__elements)"
        }
        return text
    }
}

// Test code
let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let group = dispatch_group_create()

var testSet = OrderedSet<Int>()
for i in 0..<20 {
    dispatch_group_async(group, globalQueue) {
        testSet.append(i)
    }
}
dispatch_group_notify(group, globalQueue) {
    print("\(testSet)") // unstable result
}

XCPSetExecutionShouldContinueIndefinitely()

```

I’ve checked below:

It’s OK if defined `OrderdSet` as a class (not struct).

It’s OK if using semaphore instead of using serial queue.

I would like to know the reason why the pair of struct and serial queue is unstable.

---- updated

I got the expected result with these.

1. class instead of struct

```
import Foundation
import XCPlayground

class OrderedSet<T: Equatable> {
    func append(e: T) {
        dispatch_sync(q) {
            if !self.__elements.contains(e) {
                self.__elements.append(e)
            }
        }
    }
    var elements: [T] {
        var elements: [T] = []
        dispatch_sync(q) {
            elements = self.__elements
        }
        return elements
    }
    var count: Int {
        var ret = 0
        dispatch_sync(q) {
            ret = self.__elements.count
        }
        return ret
    }
    private var __elements: [T] = []
    private let q = dispatch_queue_create("OrderedSet.private.serial.queue", DISPATCH_QUEUE_SERIAL)
}
extension OrderedSet: CustomStringConvertible {
    var description: String {
        var text = ""
        dispatch_sync(q) {
            text = "\(self.__elements.count):\(self.__elements)"
        }
        return text
    }
}

// Test code
let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let group = dispatch_group_create()

var testSet = OrderedSet<Int>()
for i in 0..<20 {
    dispatch_group_async(group, globalQueue) {
        testSet.append(i)
    }
}
dispatch_group_notify(group, globalQueue) {
    print("\(testSet)") // It's OK
}

XCPSetExecutionShouldContinueIndefinitely()

```
2. semaphore instead of serial queue

```
import Foundation
import XCPlayground

struct OrderedSet<T: Equatable> {
    mutating func append(e: T) {
        dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER)
        if !self.__elements.contains(e) {
            self.__elements.append(e)
        }
        dispatch_semaphore_signal(s)
    }
    var elements: [T] {
        var elements: [T] = []
        dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER)
        elements = self.__elements
        dispatch_semaphore_signal(s)
        return elements
    }
    var count: Int {
        var ret = 0
        dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER)
        ret = self.__elements.count
        dispatch_semaphore_signal(s)
        return ret
    }
    private var __elements: [T] = []
    private let s = dispatch_semaphore_create(1)
}
extension OrderedSet: CustomStringConvertible {
    var description: String {
        var text = ""
        dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER)
        text = "\(self.__elements.count):\(self.__elements)"
        dispatch_semaphore_signal(s)
        return text
    }
}

// Test code
let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let group = dispatch_group_create()

var testSet = OrderedSet<Int>()
for i in 0..<20 {
    dispatch_group_async(group, globalQueue) {
        testSet.append(i)
    }
}
dispatch_group_notify(group, globalQueue) {
    print("\(testSet)") // It's OK
}

XCPSetExecutionShouldContinueIndefinitely()

```
3. serial queue with OrderdSet itself.

```
import Foundation
import XCPlayground

struct OrderedSet<T: Equatable> {
    mutating func append(e: T) {
        if !self.__elements.contains(e) {
            self.__elements.append(e)
        }
    }
    var elements: [T] {
        return self.__elements
    }
    var count: Int {
        return self.__elements.count
    }
    private var __elements: [T] = []
}
extension OrderedSet: CustomStringConvertible {
    var description: String {
        return "\(self.__elements.count):\(self.__elements)"
    }
}

// Test code
let globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
let serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL)

let group = dispatch_group_create()

var testSet = OrderedSet<Int>()
for i in 0..<20 {
    dispatch_group_async(group, globalQueue) {
        dispatch_sync(serialQueue) {
            testSet.append(i)
        }
    }
}
dispatch_group_notify(group, serialQueue) {
    print("\(testSet)") // It's OK
}

XCPSetExecutionShouldContinueIndefinitely()

```