/** * (c) Copyright, Real-Time Innovations, 2025. * All rights reserved. * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef osapi_fileLock_h #define osapi_fileLock_h /* Currently, file locks are only supported in these platforms */ #if (defined(RTI_LINUX) && !defined(RTI_ANDROID)) || defined(RTI_DARWIN) \ || defined(RTI_WIN32) #define RTI_OSAPI_FILE_LOCK_SUPPORTED #endif #if defined(RTI_OSAPI_FILE_LOCK_SUPPORTED) #include "osapi/osapi_log.h" #include "osapi/osapi_type.h" #include "osapi/osapi_errorCode.h" #include "osapi/osapi_ntptime.h" #ifdef __cplusplus extern "C" { #endif /** * @internal * @defgroup RTIOsapiFileLockClass RTIOsapiFileLock * @ingroup RTIOsapiModule * * @brief OS-independent encapsulation of a file lock, which can be used to * synchronize mutual exclusion between processes. * * @attention * - The lock is advisory and must be used by all cooperating processes. * * - The lock object is **not thread-safe**: File locks only guarantee mutual * exclusion between processes. If multiple threads may access a lock object, * external synchronization (such as a mutex) is required to ensure that only * one thread at a time calls `acquire` or `release` on any lock object for the * same file. * * - The lock is **not re-entrant**: a thread cannot call `acquire` multiple * times on the same lock object without releasing it first. */ struct RTIOsapiFileLock; /** * @internal * @ingroup RTIOsapiFileLockClass * * @brief Allocate and initialize a file lock object. * * @note It is recommended to use a lock file that is independent from the * application data file when the user is trying to arbitrage access. * That is, it is preferred to use a dedicated file for synchronization, rather * than locking the data file itself. * * The common practice is to use a file with the same name as the data file and * with the `.lock` extension instead. * * @param[in] filename Name of the file to lock (including extension). * * @return Pointer to the file lock object, or `NULL` on failure. */ extern RTIOsapiDllExport struct RTIOsapiFileLock *RTIOsapiFileLock_new( const char *filename); /** * @internal * @ingroup RTIOsapiFileLockClass * * @brief Destroy the file lock object and release resources. * * @param[in] self The file lock object. */ extern RTIOsapiDllExport void RTIOsapiFileLock_delete( struct RTIOsapiFileLock *self); /** * @internal * @ingroup RTIOsapiFileLockClass * * @brief Acquire an exclusive lock on the file. * * @param[inout] self The file lock object. * * @note Permissions on the lock file upon acquiring are set to read/write for * the owner only (`S_IRUSR | S_IWUSR`) on Linux and MacOS. * Other processes should be able to use it as long as they are owned by the * same user. * * @return RTIOsapiConcurrencyErrorCode */ extern RTIOsapiDllExport RTIOsapiConcurrencyErrorCode RTIOsapiFileLock_acquire(struct RTIOsapiFileLock *self); /** * @internal * @ingroup RTIOsapiFileLockClass * * @brief Release the lock on the file. * * @param[inout] self The file lock object. * * @return RTIOsapiConcurrencyErrorCode */ extern RTIOsapiDllExport RTIOsapiConcurrencyErrorCode RTIOsapiFileLock_release(struct RTIOsapiFileLock *self); /** * @internal * @ingroup RTIOsapiFileLockClass * * @brief Check if the lock is currently held. * * @param[in] self The file lock object. * * @return `RTI_TRUE` if the lock is held, `RTI_FALSE` otherwise. */ extern RTIOsapiDllExport RTIBool RTIOsapiFileLock_isHeld(const struct RTIOsapiFileLock *self); /** * @internal * @brief Retrieve the filename associated with the file lock. * * @param[in] self The file lock object. * @param[inout] filenameBuffer Pre-allocated buffer to receive the filename. * @param[in] filenameBufferSize The size of the buffer. * * @return `RTI_TRUE` if successful, `RTI_FALSE` otherwise. */ extern RTIOsapiDllExport RTIBool RTIOsapiFileLock_getFilename( const struct RTIOsapiFileLock *self, char *filenameBuffer, size_t filenameBufferSize); #ifdef __cplusplus } #endif #endif /* RTI_OSAPI_FILE_LOCK_SUPPORTED */ #endif /* osapi_fileLock_h */