|
| 1 | +/* |
| 2 | + * Copyright (C) 2019 Codership Oy <[email protected]> |
| 3 | + * |
| 4 | + * This file is part of wsrep-API. |
| 5 | + * |
| 6 | + * Wsrep-API is free software: you can redistribute it and/or modify |
| 7 | + * it under the terms of the GNU General Public License as published by |
| 8 | + * the Free Software Foundation, either version 2 of the License, or |
| 9 | + * (at your option) any later version. |
| 10 | + * |
| 11 | + * Wsrep-API is distributed in the hope that it will be useful, |
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | + * GNU General Public License for more details. |
| 15 | + * |
| 16 | + * You should have received a copy of the GNU General Public License |
| 17 | + * along with wsrep-API. If not, see <https://www.gnu.org/licenses/>. |
| 18 | + */ |
| 19 | + |
| 20 | +/** @file wsrep_thread_service.h |
| 21 | + * |
| 22 | + * Service interface for threads, mutexes and condition variables. |
| 23 | + * The application which may provide callbacks to routines which will |
| 24 | + * be used to manage lifetime and use threads and sycnronization primitives. |
| 25 | + * |
| 26 | + * The type tags and interface methods are loosely modeled after POSIX |
| 27 | + * threading interface. |
| 28 | + * |
| 29 | + * The application must either none or all of the callbacks defined in |
| 30 | + * wsrep_thread_service structure which is defined below. |
| 31 | + * |
| 32 | + * The error codes returned by the callbacks are generally assumed to |
| 33 | + * the system error numbers defined in errno.h unless stated otherwise. |
| 34 | + * |
| 35 | + * The provider must implement and export the following functions |
| 36 | + * to provide initialization point for the service implementation: |
| 37 | + * |
| 38 | + * Version 1: |
| 39 | + * int wsrep_init_thread_service_v1(wsrep_thread_service_v1_t*) |
| 40 | + * |
| 41 | + * The application defined implementation must be initialized before |
| 42 | + * calling the initialization function and must stay functional |
| 43 | + * until the provider is unloaded. |
| 44 | + */ |
| 45 | + |
| 46 | +#ifndef WSREP_THREAD_SERVICE_H |
| 47 | +#define WSREP_THREAD_SERVICE_H |
| 48 | + |
| 49 | +#include <stddef.h> /* size_t */ |
| 50 | + |
| 51 | +#ifdef __cplusplus |
| 52 | +extern "C" |
| 53 | +{ |
| 54 | +#endif /* __cplusplus */ |
| 55 | + |
| 56 | + /* Forward declarations */ |
| 57 | + struct timespec; |
| 58 | + struct sched_param; |
| 59 | + |
| 60 | + /** Thread type tags */ |
| 61 | + typedef struct wsrep_thread_key_st wsrep_thread_key_t; |
| 62 | + typedef struct wsrep_thread_st wsrep_thread_t; |
| 63 | + /** Mutex type tags */ |
| 64 | + typedef struct wsrep_mutex_key_st wsrep_mutex_key_t; |
| 65 | + typedef struct wsrep_mutex_st wsrep_mutex_t; |
| 66 | + /** Condition variable tags */ |
| 67 | + typedef struct wsrep_cond_key_st wsrep_cond_key_t; |
| 68 | + typedef struct wsrep_cond_st wsrep_cond_t; |
| 69 | + |
| 70 | + /** |
| 71 | + * Create key for a thread with a name. This key object will be passed |
| 72 | + * to thread creation and destrunction notification callbacks. |
| 73 | + * |
| 74 | + * @param name Name of the thread. |
| 75 | + */ |
| 76 | + typedef const wsrep_thread_key_t* (*wsrep_thread_key_create_cb_t)( |
| 77 | + const char* name); |
| 78 | + |
| 79 | + /** |
| 80 | + * Create a new thread. |
| 81 | + * |
| 82 | + * @param[out] thread Newly allocated thread. |
| 83 | + * @param key Key created by wsrep_thread_key_create_cb_t |
| 84 | + * @param start_fn Pointer to start routine |
| 85 | + * @param arg Argument for start_fn |
| 86 | + * |
| 87 | + * @return Zero in case of success, non-zero error code in case of failure. |
| 88 | + */ |
| 89 | + typedef int (*wsrep_thread_create_cb_t)(const wsrep_thread_key_t* key, |
| 90 | + wsrep_thread_t** thread, |
| 91 | + void* (*start_fn)(void*), |
| 92 | + void* arg); |
| 93 | + |
| 94 | + /** |
| 95 | + * Detach a thread. |
| 96 | + * |
| 97 | + * @param thread Thread to be detached. |
| 98 | + * |
| 99 | + * @return Zero in case of error, non-zero error code in case of failure. |
| 100 | + */ |
| 101 | + typedef int (*wsrep_thread_detach_cb_t)(wsrep_thread_t* thread); |
| 102 | + |
| 103 | + /** |
| 104 | + * Compare two threads for equality. |
| 105 | + * |
| 106 | + * @params t1, t2 Threads to be compared. |
| 107 | + * |
| 108 | + * @return Non-zero value if threads are equal, zero otherwise. |
| 109 | + */ |
| 110 | + typedef int (*wsrep_thread_equal_cb_t)(wsrep_thread_t* t1, |
| 111 | + wsrep_thread_t* t2); |
| 112 | + |
| 113 | + /** |
| 114 | + * Terminate the calling thread. |
| 115 | + * |
| 116 | + * @param thread Pointer to thread. |
| 117 | + * @param retval Pointer to return value. |
| 118 | + * |
| 119 | + * This function does not return. |
| 120 | + */ |
| 121 | + typedef void __attribute__((noreturn)) (*wsrep_thread_exit_cb_t)( |
| 122 | + wsrep_thread_t* thread, void* retval); |
| 123 | + |
| 124 | + /** |
| 125 | + * Join a thread. Trying to join detached thread may cause undefined |
| 126 | + * behavior. |
| 127 | + * |
| 128 | + * @param thread Thread to be joined. |
| 129 | + * @param[out] retval Return value from the thread wthat was joined. |
| 130 | + * |
| 131 | + * @return Zero in case of success, non-zero error code in case of error. |
| 132 | + */ |
| 133 | + typedef int (*wsrep_thread_join_cb_t)(wsrep_thread_t* thread, |
| 134 | + void** retval); |
| 135 | + |
| 136 | + /** |
| 137 | + * Return a pointer to the wsrep_thread_t of the calling thread. |
| 138 | + * |
| 139 | + * @return Pointer to wsrep_thread_t associated with current thread. |
| 140 | + */ |
| 141 | + typedef wsrep_thread_t* (*wsrep_thread_self_cb_t)(void); |
| 142 | + |
| 143 | + /** |
| 144 | + * Set the scheduling policy for the thread. |
| 145 | + * |
| 146 | + * @param thread Thread for which sceduing policy should be changed. |
| 147 | + * @param policy New scheduling policy for the thread. |
| 148 | + * @param param New scheduling parameters for the thread. |
| 149 | + */ |
| 150 | + typedef int (*wsrep_thread_setschedparam_cb_t)( |
| 151 | + wsrep_thread_t* thread, int policy, const struct sched_param* param); |
| 152 | + |
| 153 | + /** |
| 154 | + * Get the current scheduling policy for the thread. |
| 155 | + * |
| 156 | + * @param thread Thread. |
| 157 | + * @param policy Pointer to location where the scheduling policy will |
| 158 | + * will be stored in. |
| 159 | + * @param Param Pointer to location where the current scheduling |
| 160 | + * parameters will be stored. |
| 161 | + */ |
| 162 | + typedef int (*wsrep_thread_getschedparam_cb_t)(wsrep_thread_t* thread, |
| 163 | + int* policy, |
| 164 | + struct sched_param* param); |
| 165 | + /** |
| 166 | + * Create key for a mutex with a name. This key object must be passed |
| 167 | + * to mutex creation callback. |
| 168 | + * |
| 169 | + * @param name Name of the mutex. |
| 170 | + * |
| 171 | + * @return Const pointer to mutex key. |
| 172 | + */ |
| 173 | + typedef const wsrep_mutex_key_t* (*wsrep_mutex_key_create_cb_t)( |
| 174 | + const char* name); |
| 175 | + |
| 176 | + /** |
| 177 | + * Create a mutex. |
| 178 | + * |
| 179 | + * @param key Mutex key obtained via wsrep_mutex_key_create_cb call. |
| 180 | + * @param memblock Optional memory block allocated by the provider |
| 181 | + * which can be used by the implementation to store |
| 182 | + * the mutex. |
| 183 | + * @param memblock_size Size of the optional memory block. |
| 184 | + * |
| 185 | + * @return Pointer to wsrep_mutex_t object or NULL in case of failure. |
| 186 | + */ |
| 187 | + typedef wsrep_mutex_t* (*wsrep_mutex_init_cb_t)( |
| 188 | + const wsrep_mutex_key_t* key, void* memblock, size_t memblock_size); |
| 189 | + |
| 190 | + /** |
| 191 | + * Destroy a mutex. This call must consume the mutex object. |
| 192 | + * |
| 193 | + * @param mutex Mutex to be destroyed. |
| 194 | + */ |
| 195 | + typedef int (*wsrep_mutex_destroy_cb_t)(wsrep_mutex_t* mutex); |
| 196 | + |
| 197 | + /** |
| 198 | + * Lock a mutex. |
| 199 | + * |
| 200 | + * @param mutex Mutex to be locked. |
| 201 | + * |
| 202 | + * @return Zero on success, non-zero error code on error. |
| 203 | + */ |
| 204 | + typedef int (*wsrep_mutex_lock_cb_t)(wsrep_mutex_t* mutex); |
| 205 | + |
| 206 | + /** |
| 207 | + * Try to lock a mutex. |
| 208 | + * |
| 209 | + * @param Mutex to be locked. |
| 210 | + * |
| 211 | + * @return Zero if mutex was succesfully locked. |
| 212 | + * @return EBUSY if the mutex could not be acquired because it was already |
| 213 | + * locked. |
| 214 | + * @return Non-zero error code on any other error. |
| 215 | + */ |
| 216 | + typedef int (*wsrep_mutex_trylock_cb_t)(wsrep_mutex_t* mutex); |
| 217 | + |
| 218 | + /** |
| 219 | + * Unlock a mutex. |
| 220 | + * |
| 221 | + * @param mutex Mutex to be unlocked. |
| 222 | + * |
| 223 | + * @return Zero on success, non-zero on error. |
| 224 | + */ |
| 225 | + typedef int (*wsrep_mutex_unlock_cb_t)(wsrep_mutex_t* mutex); |
| 226 | + |
| 227 | + /** |
| 228 | + * Create key for a condition variable with a name. This key |
| 229 | + * must be passed to wsrep_cond_create_cb when creating a new |
| 230 | + * condition variable. |
| 231 | + * |
| 232 | + * @param name Name of the condition variable. |
| 233 | + * |
| 234 | + * @return Allocated key object. |
| 235 | + */ |
| 236 | + typedef const wsrep_cond_key_t* (*wsrep_cond_key_create_cb_t)( |
| 237 | + const char* name); |
| 238 | + |
| 239 | + /** |
| 240 | + * Create a new condition variable. |
| 241 | + * |
| 242 | + * @param key Const pointer to key object created by |
| 243 | + * wsrep_cond_key_create_cb. |
| 244 | + * @param memblock Optional memory block allocated by the provider |
| 245 | + * which can be used by the implementation to store |
| 246 | + * the mutex. |
| 247 | + * @param memblock_size Size of the optional memory block. |
| 248 | + * |
| 249 | + * @return Pointer to new condition variable. |
| 250 | + */ |
| 251 | + typedef wsrep_cond_t* (*wsrep_cond_init_cb_t)(const wsrep_cond_key_t* key, |
| 252 | + void* memblock, |
| 253 | + size_t memblock_size); |
| 254 | + |
| 255 | + /** |
| 256 | + * Destroy a condition variable. This call must consume the condition |
| 257 | + * variable object. |
| 258 | + * |
| 259 | + * @param cond Condition variable to be destroyed. |
| 260 | + * |
| 261 | + * @return Zero on success, non-zero on error. |
| 262 | + */ |
| 263 | + typedef int (*wsrep_cond_destroy_cb_t)(wsrep_cond_t* cond); |
| 264 | + |
| 265 | + /** |
| 266 | + * Wait for condition. |
| 267 | + * |
| 268 | + * @param cond Condition variable to wait for. |
| 269 | + * @param mutex Mutex associated to the condition variable. The mutex |
| 270 | + * may be unlocked for the duration of the wait. |
| 271 | + * |
| 272 | + * @return Zero on success, non-zero on error. |
| 273 | + */ |
| 274 | + typedef int (*wsrep_cond_wait_cb_t)(wsrep_cond_t* cond, |
| 275 | + wsrep_mutex_t* mutex); |
| 276 | + |
| 277 | + /** |
| 278 | + * Perform timed wait on condition. |
| 279 | + * |
| 280 | + * @param cond Condition to wait for. |
| 281 | + * @param mutex Mutex associated to the condition variable. The mutex |
| 282 | + * may be unlocked for the duration of the wait. |
| 283 | + * @param wait_until System time to wait until before returning from the |
| 284 | + * the timed wait. |
| 285 | + * |
| 286 | + * @return Zero on success. |
| 287 | + * @return ETIMEDOUT if the time specified by wait_until has passed. |
| 288 | + * @return Non-zero error code on other error. |
| 289 | + */ |
| 290 | + typedef int (*wsrep_cond_timedwait_cb_t)(wsrep_cond_t* cond, |
| 291 | + wsrep_mutex_t* mutex, |
| 292 | + const struct timespec* wait_until); |
| 293 | + |
| 294 | + /** |
| 295 | + * Signal a condition variable. This will wake up at least one of |
| 296 | + * the threads which is waiting for the condition. |
| 297 | + * |
| 298 | + * @param cond Condition variable to signal. |
| 299 | + * |
| 300 | + * @return Zero on success, non-zero on failure. |
| 301 | + */ |
| 302 | + typedef int (*wsrep_cond_signal_cb_t)(wsrep_cond_t* cond); |
| 303 | + |
| 304 | + /** |
| 305 | + * Broadcast a signal to condition variable. This will wake up |
| 306 | + * all the threads which are currently waiting on condition variable. |
| 307 | + * |
| 308 | + * @param cond Condition variable to broadcast the signal to. |
| 309 | + * |
| 310 | + * @return Zero on success, non-zero on failure. |
| 311 | + */ |
| 312 | + typedef int (*wsrep_cond_broadcast_cb_t)(wsrep_cond_t* cond); |
| 313 | + |
| 314 | + typedef struct wsrep_thread_service_v1_st |
| 315 | + { |
| 316 | + /* Threads */ |
| 317 | + wsrep_thread_key_create_cb_t thread_key_create_cb; |
| 318 | + wsrep_thread_create_cb_t thread_create_cb; |
| 319 | + wsrep_thread_detach_cb_t thread_detach_cb; |
| 320 | + wsrep_thread_equal_cb_t thread_equal_cb; |
| 321 | + wsrep_thread_exit_cb_t thread_exit_cb; |
| 322 | + wsrep_thread_join_cb_t thread_join_cb; |
| 323 | + wsrep_thread_self_cb_t thread_self_cb; |
| 324 | + wsrep_thread_setschedparam_cb_t thread_setschedparam_cb; |
| 325 | + wsrep_thread_getschedparam_cb_t thread_getschedparam_cb; |
| 326 | + /* Mutexes */ |
| 327 | + wsrep_mutex_key_create_cb_t mutex_key_create_cb; |
| 328 | + wsrep_mutex_init_cb_t mutex_init_cb; |
| 329 | + wsrep_mutex_destroy_cb_t mutex_destroy_cb; |
| 330 | + wsrep_mutex_lock_cb_t mutex_lock_cb; |
| 331 | + wsrep_mutex_trylock_cb_t mutex_trylock_cb; |
| 332 | + wsrep_mutex_unlock_cb_t mutex_unlock_cb; |
| 333 | + /* Condition variables */ |
| 334 | + wsrep_cond_key_create_cb_t cond_key_create_cb; |
| 335 | + wsrep_cond_init_cb_t cond_init_cb; |
| 336 | + wsrep_cond_destroy_cb_t cond_destroy_cb; |
| 337 | + wsrep_cond_wait_cb_t cond_wait_cb; |
| 338 | + wsrep_cond_timedwait_cb_t cond_timedwait_cb; |
| 339 | + wsrep_cond_signal_cb_t cond_signal_cb; |
| 340 | + wsrep_cond_broadcast_cb_t cond_broadcast_cb; |
| 341 | + } wsrep_thread_service_v1_t; |
| 342 | + |
| 343 | +#ifdef __cplusplus |
| 344 | +} |
| 345 | + |
| 346 | +#define WSREP_THREAD_SERVICE_INIT_FUNC "wsrep_init_thread_service_v1" |
| 347 | + |
| 348 | +#endif /* __cplusplus */ |
| 349 | +#endif /* WSREP_THREAD_SERVICE_H */ |
0 commit comments