# server.Server.with_channel_lock

- **Module:** server.Server
- **Package:** libtmux
- **Language:** Rust
- **Kind:** method
- **Source:** https://github.com/libtmux/libtmux-rs/blob/f0e37052c232636b61d095817046e6bfc8f2ca40/crates/libtmux/src/server/channels.rs#L72
- **Page:** https://libtmux.org/en/rs/latest/reference/server-server-with_channel_lock/

```
server.Server.with_channel_lock(self, channel: &str, operation: impl AsyncFnOnce(&Self) -> Result<T, E>) -> Result<T, crate::ScopeError<T, E>>
```

Hold a `wait-for` channel for the length of an operation.

[`Self::lock_channel`] and [`Self::unlock_channel`] as a pair, so a
locker that returns early, fails, or panics still releases the
channel: a lock left held wedges every later locker on the server.

# Errors

[`crate::ScopeError::Creation`] when tmux refuses the lock or the lock
runs out of time, `Operation` when the body fails, and `Cleanup` when
the unlock fails after the body succeeded.

# Cancel safety

Nothing is left held by a drop. The lock is taken and released in tasks
of their own, so a scope dropped while its lock is still queued unlocks
once tmux grants it, as [`Self::lock_channel`] describes.

## Example

```rust
let guard = libtmux::test::TestServer::new().await?;
let server = guard.server();

let count = server
    .with_channel_lock("deploy", async |server| {
        Ok::<_, libtmux::Error>(server.sessions().await?.len())
    })
    .await?;

// The channel is free again, so the next locker is not blocked.
server.lock_channel("deploy").await?;
server.unlock_channel("deploy").await?;
guard.shutdown().await?;
```
