{"id":940,"url":"https://github.com/stickytools/sticky-locking","last_synced_at":"2026-01-28T02:03:20.983Z","repository":{"id":62456082,"uuid":"129653552","full_name":"stickytools/sticky-locking","owner":"stickytools","description":"A general purpose embedded hierarchical lock manager used to build highly concurrent applications of all types. Same type of locker used in many of the large and small DBMSs in existence today.","archived":false,"fork":false,"pushed_at":"2019-02-23T15:54:47.000Z","size":189,"stargazers_count":2,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-14T15:12:56.593Z","etag":null,"topics":["concurrency","conditions","database","embedded","hierarchical","hierarchical-locking","high-concurrency","ios","linux","lock","lock-manager","locking","macos","mutex","osx","readers-writer-lock","swift","swift-4","swift-framework","swift-package-manager"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stickytools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-15T21:44:29.000Z","updated_at":"2021-06-15T05:36:24.000Z","dependencies_parsed_at":"2022-11-02T00:15:12.326Z","dependency_job_id":null,"html_url":"https://github.com/stickytools/sticky-locking","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/stickytools/sticky-locking","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stickytools%2Fsticky-locking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stickytools%2Fsticky-locking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stickytools%2Fsticky-locking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stickytools%2Fsticky-locking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stickytools","download_url":"https://codeload.github.com/stickytools/sticky-locking/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stickytools%2Fsticky-locking/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28833392,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T23:29:49.665Z","status":"online","status_checked_at":"2026-01-28T02:00:06.943Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["concurrency","conditions","database","embedded","hierarchical","hierarchical-locking","high-concurrency","ios","linux","lock","lock-manager","locking","macos","mutex","osx","readers-writer-lock","swift","swift-4","swift-framework","swift-package-manager"],"created_at":"2024-01-05T20:15:35.092Z","updated_at":"2026-01-28T02:03:20.967Z","avatar_url":"https://github.com/stickytools.png","language":"Swift","readme":"# StickyLocking ![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-lightgray.svg?style=flat)\n\n\u003ca href=\"https://github.com/stickytools/sticky-locking/\" target=\"_blank\"\u003e\n   \u003cimg src=\"https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20watchOS%20%7C%20tvOS%20%7C%20Linux%20-lightgray.svg?style=flat\" alt=\"Platforms: iOS | macOS | watchOS | tvOS | Linux\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/stickytools/sticky-locking/\" target=\"_blank\"\u003e\n   \u003cimg src=\"https://img.shields.io/badge/Swift-4.2-orange.svg?style=flat\" alt=\"Swift 4.2\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/stickytools/sticky-locking/\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/cocoapods/v/StickyLocking.svg?style=flat\" alt=\"Pod version\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://travis-ci.org/stickytools/sticky-locking\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://travis-ci.org/stickytools/sticky-locking.svg?branch=master\" alt=\"travis-ci.org\" /\u003e\n\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/stickytools/sticky-locking\" target=\"_blank\"\u003e\n  \u003cimg src=\"https://codecov.io/gh/stickytools/sticky-locking/branch/master/graph/badge.svg\" alt=\"Codecov\" /\u003e\n\u003c/a\u003e\n\n---\n\n**StickyLocking** is a general purpose embedded lock manager which  allows for locking any resource hierarchy.  Installable Lock modes allow for customization of the locking system that can meet the needs of almost any locking scenario.\n\n## Documentation\n\nSticky Locking provides the `Locker` class which is a high-level locking system designed to facilitate many different concurrency use cases including simple readers-writer locks which provide shared access for read operations and\nexclusive access for write operations to more complex hierarchical locking schemes used to power database file,\ndatabase, page, and row level locking.\n\nSticky Locking also provides a low-level mutual exclusion lock through the `Mutex` class to protect critical sections of\nyour code.  In addition, wait conditions (`Condition`) are provided to allow for threads to wait for a mutex to\nbecome available.\n\nThe mutual exclusion lock is provided through the `Mutex` class while wait conditions can be created with the\n`Condition` class.  Internally, the higher level components are implemented using these two primitives, and other\nmodules in the Sticky Tools suite of libraries also use the mutex for protecting various critical sections of code.\n\n### Hierarchical Locker\n\nSticky Locking provides the `Locker` class which is a high-level locking system designed to facilitate many different\nconcurrency use cases including simple readers-writer locks which provide shared access for read operations and\nexclusive access for write operations to more complex hierarchical locking schemes used to power database file,\ndatabase, page, and row level locking.\n\nThe `Locker` is highly configurable to your specific use case using three interconnected constructs.\n\n1) The `LockMode` defines the symbols your application will use to specify the lock modes various resources can be locked in.\n2) The `CompatibilityMatrix` defines whether two modes can be granted concurrently for the same resource (is it shared or exclusive).\n3) The `GroupModeMatrix` defines the composite mode a group of granted locks take on when granted together.\n\nSticky has two built-in sets of these values in the following enums.\n\n`SharedExclusiveLockMode` which is a simple readers-writer system used to provide shared read access and exclusive\nwrite access.\n\nAn example use case for this mode may be to protect access to a file or many files which require all readers to be able\nto share access to the file and writers to be granted exclusive access forcing readers and writers to wait until the\nwrite operation is complete before they proceed.\n\n`ExtendedLockMode` an extended mode that includes intention and update modes which can be used for advanced database\ntype use cases.  This LockMode set was designed to be used by other models in the Sticky Tools suite of libraries.\n\nYou are free to define your own LockMode set depending on your use case, from simpler mode structures to more complex,\nSticky Locking will adapt to the mode given.\n\n#### Defining Locker Behavior\n\nThe `Locker`s behavior is defined by the `LockMode`, `CompatibilityMatrix`, and `GroupModeMatrix`. These types and\nstructures define how the Locker will grant requests for lock modes.\n\nA `LockMode` is an enum entry that defines a specific mode of the lock.  These modes are user defined\n\n##### Lock Modes\n\nLock modes determine the symbols used to define the modes a lock can be in.\n\nHere is an example of a simple lock mode definition:\n```swift\n    enum MyLockMode: LockMode {\n        case S  /// Shared\n        case X  /// Exclusive\n    }\n```\nThe mode on it's own only defines the symbols that can be used.  You must define a `CompatibilityMatrix` and `GroupModeMatrix` to describe how the various modes interact with each other.\n\n\u003e Note: Sticky Locking defines two built in `LockMode` enums along with corresponding compatibility and group mode matrix's.  A simple readers-writer type named `SharedExclusiveLockMode` and an extended mode named `ExtendedLockMode` which is suitable for advanced data storage applications.\n\n##### Lock Mode Compatibility\n\nThe ability to share a lock mode with another request/thread is determined by the lock mode compatibility matrix\nsupplied for the lock mode.  For every new lock request, the matrix is checked and if the value at the index of the\ncurrent lock mode and the requested lock mode is `true` the lock will be granted concurrently, otherwise the request\nwill queue and wait.\n```swift\n    let compatibilityMatrix: CompatibilityMatrix\u003cMyLockMode\u003e\n            = [\n                /*               Shared, Exclusive  */\n                /* Shared    */  [true,    false],\n                /* Exclusive */  [false,   false],\n              ]\n```\n\n##### Lock Group Mode\n\nWhen multiple requests are compatible and granted concurrently the lock mode of the group must be calculated.  This\nis called the group mode.  A new request is compatible with the members of the group if it is compatible with the\ngroup mode.\n\nSticky Locking uses the `GroupModeMatrix` to determine the group mode when a new request joins the group.\n```swift\n    let groupModeMatrix: GroupModeMatrix\u003cMyLockMode\u003e\n            = [\n                /* Requested     Shared, Exclusive  */\n                /* Shared    */  [S,     X],\n                /* Exclusive */  [X,     X],\n              ]\n```\n\n\u003e See [Lock Wait State \u0026 Grant Behavior](Documentation/Lock\u0026#32;Wait\u0026#32;State\u0026#32;\u0026amp;\u0026#32;Grant\u0026#32;Behavior.md) for a more detailed description and examples of how the locker behaves during locking.\n\n#### Built-in Lock Modes\n\nSticky Locking contains two pre-defined `LockMode` enums and associated matrix's for use with various use cases.\n\n##### Shared-Exclusive Lock Mode\n\nA Shared Exclusive lock (a.k.a. readers-writer or multi-reader) allows concurrent access for read-only\noperations, while write operations gain exclusive access.\n\nThis allows multiple readers to gain shared access to a resource blocking all writers until no more\nreaders are reading.  Writers gain exclusive access to the resource blocking all other readers and writers\nuntil the operation is complete.\n\nThe defined modes are:\n\n * S - Shared (Read)\n * X - Exclusive (Write)\n\nThe default `CompatibilityMatrix` is defined as:\n\n| Requested |    S   |    X   |\n|:---------:|:------:|:------:|\n|  **S**    |\u0026#x2714;|\u0026#x2718;|\n|  **X**    |\u0026#x2718;|\u0026#x2718;|\n\nThe default `GroupModeMatrix` is defined  as:\n\n| Requested |   S    |    X   |\n|:---------:|:------:|:------:|\n|  **S**    |   S    |    X   |\n|  **X**    |   X    |    X   |\n\n\n##### Extended Lock Mode\n\nThe `ExtendedLockMode` is a predefined `LockMode` implementation that can be used for complex database type applications.  It defines\nan extended set of lock modes including Update and Intention modes.\n\nThe defined modes are:\n\n  * IS - Intention Shared\n  * IX - Intention Exclusive\n  * S - Shared\n  * SIX - Shared Intention Exclusive\n  * U - Update\n  * X - Exclusive\n\nThe default `CompatibilityMatrix` is defined as:\n\n| Requested |   IS   |   IX   |    S   |   SIX  |    U   |    X   |\n|:---------:|:------:|:------:|:------:|:------:|:------:|:------:|\n|  **IS**   |\u0026#x2714;|\u0026#x2714;|\u0026#x2714;|\u0026#x2714;|\u0026#x2714;|\u0026#x2718;|\n|  **IX**   |\u0026#x2714;|\u0026#x2714;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\n|  **S**    |\u0026#x2714;|\u0026#x2718;|\u0026#x2714;|\u0026#x2718;|\u0026#x2714;|\u0026#x2718;|\n|  **SIX**  |\u0026#x2714;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\n|  **U**    |\u0026#x2714;|\u0026#x2718;|\u0026#x2714;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\n|  **X**    |\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\u0026#x2718;|\n\nThe default `GroupModeMatrix` is defined as:\n\n| Requested |   IS   |   IX   |   S    |   SIX  |    U   |    X   |\n|:---------:|:------:|:------:|:------:|:------:|:------:|:------:|\n|  **IS**   |   IS   |   IX   |   S    |   SIX  |    U   |    X   |\n|  **IX**   |   IX   |   IX   |   SIX  |   SIX  |    X   |    X   |\n|  **S**    |   S    |   SIX  |   S    |   SIX  |    U   |    X   |\n|  **SIX**  |   SIX  |   SIX  |   SIX  |   SIX  |    SIX |    X   |\n|  **U**    |   U    |   X    |   U    |   SIX  |    U   |    X   |\n|  **X**    |   X    |   X    |   X    |   X    |    X   |    X   |\n\n\n#### Resources \u0026 Hashing\n\nThe `Locker` will lock and unlock any `Hashable` resource and it distinguishes the lock resources by the hash value,\ntherefore care must be taken to create a hashing algorithm that ensure uniqueness between individual objects of the\nsame type as well as the hash values between different types.\n\nIf two resources hash to the same hash value, and the two requested modes are incompatible, then the collision may\ncause spurious waits.\n\nAlso keep in mind that the hashValue should never change for the resource.  If the hashValue changes over the life of the\nresource, the locker will consider it a different resource each time the hashValue changes.  For instance, an Array\u003c\u003e hashValue\nchanges with each element that is added or removed from the array, therefore the Array\u003c\u003e instance itself could not be used\nas a lock resource on its own.  You would have to use a surrogate Resource such as a fixed String or integer as the Resource\nidentifier.\n\n### Mutexes \u0026 Conditions\n\nSticky Locking also provides a low-level mutual exclusion lock through the `Mutex` class to protect critical sections of your code.  In addition, wait conditions (`Condition`) are provided to allow for threads to wait for a mutex to become available.\n\nThe mutual exclusion lock is provided through the `Mutex` class while wait conditions can be created with the `Condition` class.  Internally, the higher level components are implemented using these two primitives, and other modules in the Sticky Tools suite of libraries also use the mutex for protecting various critical sections of code.\n\n## Sources and Binaries\n\nYou can find the latest sources and binaries on [github](https://github.com/stickytools/sticky-locking).\n\n## Communication and Contributions\n\n- If you **found a bug**, _and can provide steps to reliably reproduce it_, [open an issue](https://github.com/stickytools/sticky-locking/issues).\n- If you **have a feature request**, [open an issue](https://github.com/stickytools/sticky-locking/issues).\n- If you **want to contribute**\n   - Fork it! [StickyLocking repository](https://github.com/stickytools/sticky-locking)\n   - Create your feature branch: `git checkout -b my-new-feature`\n   - Commit your changes: `git commit -am 'Add some feature'`\n   - Push to the branch: `git push origin my-new-feature`\n   - Submit a pull request :-)\n\n## Installation\n\n### Swift Package Manager\n\n**StickyLocking** supports dependency management via Swift Package Manager on All Apple OS variants as well as Linux.\n\nPlease see [Swift Package Manager](https://swift.org/package-manager/#conceptual-overview) for further information.\n\n### CocoaPods\n\nStickyLocking is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile:\n\n```ruby\n   pod \"StickyLocking\"\n```\n\n## Minimum Requirements\n\nBuild Environment\n\n| Platform | Swift | Swift Build | Xcode |\n|:--------:|:-----:|:----------:|:------:|\n| Linux    | 4.2 | \u0026#x2714; | \u0026#x2718; |\n| OSX      | 4.2 | \u0026#x2714; | Xcode 10.0 |\n\nMinimum Runtime Version\n\n| iOS |  OS X | tvOS | watchOS | Linux |\n|:---:|:-----:|:----:|:-------:|:------------:|\n| 8.0 | 10.10 | 9.0  |   2.0   | Ubuntu 14.04, 16.04, 16.10 |\n\n\u003e **Note:**\n\u003e\n\u003e To build and run on **Linux** we have a a preconfigure **Vagrant** file located at [https://github.com/tonystone/vagrant-swift](https://github.com/stickytools/vagrant-swift)\n\u003e\n\u003e See the [README](https://github.com/tonystone/vagrant-swift/blob/master/README.md) for instructions.\n\u003e\n\n## Author\n\nTony Stone ([https://github.com/tonystone](https://github.com/tonystone))\n\n## License\n\nStickyLocking is released under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)\n","funding_links":[],"categories":["Concurrency"],"sub_categories":["Linter"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstickytools%2Fsticky-locking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstickytools%2Fsticky-locking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstickytools%2Fsticky-locking/lists"}