VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
sys_semaphore.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24/**
25 * @file sys_semaphore.h
26 * @brief Named, cross-process counting semaphore backed by the OS IPC layer.
27 *
28 * @details
29 * @c SysSemaphore wraps a named POSIX semaphore (on Linux/macOS) or a named
30 * Win32 semaphore to allow synchronisation between independent processes
31 * (or between processes and drivers) via a shared name in the OS namespace.
32 *
33 * Lifecycle:
34 * -# Construct the @c SysSemaphore object.
35 * -# Call @c attach(name) to create or open a named semaphore.
36 * -# Use @c acquire() / @c release() for P/V operations.
37 * -# Call @c detach(force) to close the handle. If @p force is @c true the
38 * semaphore is also removed from the OS namespace.
39 * -# The destructor calls @c detach() automatically.
40 *
41 * @note
42 * - The initial count passed to the constructor is only used when the
43 * semaphore is @b created by @c attach(). If the semaphore already exists
44 * in the OS namespace the constructor count is ignored and the existing
45 * value is used.
46 * - Unlike @c Semaphore, this class may throw on @c attach() failures
47 * (e.g., permission denied, namespace exhausted).
48 * - Semaphore names on POSIX must start with '/' (e.g., @c "/vlink_ready").
49 * On Windows any non-empty string is accepted.
50 *
51 * @par Example
52 * @code
53 * // Process A (server) creates the semaphore:
54 * vlink::SysSemaphore sem(0);
55 * sem.attach("/vlink_ready");
56 * do_init();
57 * sem.release(); // signal Process B
58 *
59 * // Process B (client) opens the same semaphore:
60 * vlink::SysSemaphore sem;
61 * sem.attach("/vlink_ready");
62 * sem.acquire(); // blocks until Process A releases
63 * @endcode
64 */
65
66#pragma once
67
68#include <memory>
69#include <string>
70
71#include "./macros.h"
72
73namespace vlink {
74
75/**
76 * @class SysSemaphore
77 * @brief Named cross-process counting semaphore.
78 *
79 * @details
80 * Backed by the OS named-semaphore API (POSIX @c sem_open or Win32
81 * @c CreateSemaphore) to support synchronisation across process boundaries.
82 */
84 public:
85 /**
86 * @brief Sentinel value for @c acquire() meaning "wait indefinitely".
87 */
88 static constexpr int kInfinite{-1};
89
90 /**
91 * @brief Constructs a @c SysSemaphore with the given initial count.
92 *
93 * @details
94 * The semaphore is not yet attached to any OS name. Call @c attach()
95 * before using @c acquire() or @c release().
96 *
97 * @param count Initial count used when a new named semaphore is created
98 * by @c attach() (default: 0).
99 */
100 explicit SysSemaphore(size_t count = 0);
101
102 /**
103 * @brief Destructor. Calls @c detach() if the semaphore is still attached.
104 */
106
107 /**
108 * @brief Creates or opens a named semaphore with the given name.
109 *
110 * @details
111 * If a semaphore with @p name already exists in the OS namespace, it is
112 * opened and the constructor-provided initial count is ignored. If it does
113 * not exist it is created with that count.
114 *
115 * @param name OS semaphore name (POSIX: must start with '/').
116 * @return @c true on success, @c false if the semaphore could not be created
117 * or opened.
118 */
119 bool attach(const std::string& name);
120
121 /**
122 * @brief Closes the semaphore handle and optionally removes it from the
123 * OS namespace.
124 *
125 * @details
126 * After @c detach(), @c is_attached() returns @c false.
127 *
128 * @param force If @c true, the semaphore is unlinked from the OS namespace
129 * (other processes lose access). Default: @c true.
130 * @return @c true on success, @c false if not attached or unlink failed.
131 */
132 bool detach(bool force = true);
133
134 /**
135 * @brief Decrements the semaphore counter by @p n, blocking if necessary.
136 *
137 * @details
138 * Blocks the caller until @p n permits are available or @p timeout_ms
139 * milliseconds elapse.
140 *
141 * @param n Number of permits to acquire (default: 1).
142 * @param timeout_ms Maximum time to wait in milliseconds.
143 * Use @c kInfinite (-1) to wait indefinitely (default).
144 * @return @c true if permits were acquired, @c false on timeout or error.
145 *
146 * @pre @c is_attached() must be @c true.
147 */
148 bool acquire(size_t n = 1, int timeout_ms = kInfinite);
149
150 /**
151 * @brief Increments the semaphore counter by @p n.
152 *
153 * @details
154 * Wakes at most @p n threads (from any process) blocked in @c acquire().
155 *
156 * @param n Number of permits to release (default: 1).
157 *
158 * @pre @c is_attached() must be @c true.
159 */
160 void release(size_t n = 1);
161
162 /**
163 * @brief Returns @c true if the semaphore is currently attached to an OS name.
164 *
165 * @return @c true if attached, @c false otherwise.
166 */
167 [[nodiscard]] bool is_attached() const;
168
169 /**
170 * @brief Returns the current count of the semaphore.
171 *
172 * @details
173 * The value is a snapshot and may change immediately after the call.
174 * Intended for diagnostics only.
175 *
176 * @return Current semaphore count, or 0 if not attached or unsupported on
177 * the current backend.
178 */
179 [[nodiscard]] size_t get_count() const;
180
181 private:
182 std::unique_ptr<struct SysSemaphoreImpl> impl_;
183
185};
186
187} // namespace vlink
Platform-independent macro definitions for the VLink library.
#define VLINK_EXPORT
Definition macros.h:85
#define VLINK_DISALLOW_COPY_AND_ASSIGN(classname)
Deletes the copy constructor and copy-assignment operator of classname.
Definition macros.h:184