README.md

# RWlock

[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/rwlock/)

A concurrent **Readers/Writer lock** implementation built on `GenServer`.

`RWLock` allows multiple readers to acquire a shared (`:sh_lock`) lock
simultaneously, while ensuring that only one writer (`:ex_lock`) can hold
an exclusive lock at any given time.

This module manages lock ownership across processes and ensures correct
coordination between readers and writers for a given resource key (referred to as `on`).

## Features

  * Multiple readers can hold a lock concurrently (`sh_lock`)
  * Only one writer can hold a lock exclusively (`ex_lock`)
  * Fair queueing via an internal `:queue` structure
  * Lock ownership tracking via process identifiers
  * Automatic wake-up of waiting processes when a lock is released

## Installation

The package can be installed by adding `rwlock` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:rwlock, "~> 0.1.1"}
  ]
end
```

This library implements a RW Locking as a process that you would generally start
under a supervision tree.

```elixir
defmodule MyApp.Application do
  @moduledoc false

  use Application

  @impl true
  def start(_type, _args) do
    children = [
      {RWLock, name: MyApp.RWLock}
    ]

    Supervisor.start_link(children, strategy: :one_for_one)
  end
end
```
## Example
    iex> RWLock.start_link()
    iex> RWLock.sh_lock(:any_term1)
    :ok
    iex> RWLock.sh_lock(:any_term1)
    :ok
    iex> RWLock.ex_lock(:any_term2)
    :ok
    iex> RWLock.unlock(:any_term1)
    :ok
    iex> RWLock.unlock(:any_term1)
    :ok
    iex> RWLock.unlock(:any_term2)
    :ok

## Lock Structure

Internally, each lock entry is a map with these keys:

    %{
      locked?: boolean(),
      type: :ex | :sh | nil,
      readers: MapSet.t(),
      wlist: :queue.t(),
      on: any()
    }

This structure is maintained per `on` key in the GenServer’s state.

## Copyright and License

Copyright (c) 2025, Hamad Al Marri

This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the [LICENSE](./LICENSE) file for more details.