# Actor Reentrancy

**URL:** <https://forums.swift.org/t/actor-reentrancy/59484>\
**Category:** Using Swift\
**Tags:** concurrency\
**Created:** [August 5, 2022, 7:07am UTC](https://forums.swift.org/t/actor-reentrancy/59484 "2022-08-05T07:07:29Z")\
**Posts on this page:** 1\
**Showing post:** 11

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [May 19, 2023, 12:45am UTC](https://forums.swift.org/t/actor-reentrancy/59484/11 "2023-05-19T00:45:06Z")

</div>

> [@CrownedPhoenix](#):
>
> ```swift
> actor ActorSemaphore {
> private let sem: DispatchSemaphore
> 
> init(value: Int) {
> sem = DispatchSemaphore(value: value)
> }
> 
> ```

I might be wrong now, but using a `DispatchSemaphore` in an `actor` has proved to be problematic in the past when I was trying to do something similar.

I think the work around was to use `continuations` instead. (When I find the example code, I will add it here.)

@John_McCall, could you shed some light on this to educate us please?

> **Code Using Continuations**
>
> ```swift
> // Channel.swift
> 
> extension V3 {
> actor Channel<T> {
> private var store = [T?] ()
> private var waiters = [UnsafeContinuation <T?, Never>] ()
> 
> func put (_ u: T?) {
> store.append(u)
> if ! waiters.isEmpty {
> waiters.removeFirst().resume (returning: store.removeFirst ())
> }
> }
>         
> func get () async -> T? {
> if store.isEmpty {
> return await withUnsafeContinuation {
> waiters.append ($0)
> }
> }
> else {
> let value = store.removeFirst()
> return value
> }
> }
>         
> var state: (packets: Int, waiters: Int) {
> return (store.count, waiters.count)
> }
>         
> var description: String {
> return "\(state)"
> }
> }
> }
> 
> ```

> **Original Example**
>
> [Source](https://forums.swift.org/t/semaphore-alternatives-for-structured-concurrency/59353/3)
> 
> ```swift
> actor Semaphore {
> private var count: Int
> private var waiters: [CheckedContinuation<Void, Never>] = []
> 
> init(count: Int = 0) {
> self.count = count
> }
> 
> func wait() async {
> count -= 1
> if count >= 0 { return }
> await withCheckedContinuation {
> waiters.append($0)
> }        
> }
> 
> func release(count: Int = 1) {
> assert(count >= 1)
> self.count += count
> for _ in 0..<count {
> if waiters.isEmpty { return }
> waiters.removeFirst().resume()
> }
> }
> }
> 
> ```

---

_[View the full topic](https://forums.swift.org/t/actor-reentrancy/59484)._
