Mercurial > foo_out_sdl
comparison foosdk/sdk/foobar2000/SDK/file_lock_manager.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 /* | |
| 4 File lock management API | |
| 5 Historical note: while this API was first published in a 2018 release of the SDK, it had been around for at least a decade and is supported in all fb2k versions from 0.9 up. | |
| 6 The semantics are similar to those of blocking POSIX flock(). | |
| 7 Since read locks are expected to be held for a long period of time - for an example, when playing an audio track, a holder of such lock can query whether someone else is waiting for this lock to be released. | |
| 8 Various audio file operations performed by fb2k core use file locks to synchronize access to the files - in particular, to allow graceful updates of tags on the currently playing track. | |
| 9 | |
| 10 Usage examples: | |
| 11 If you want to write tags to an audio file, using low level methods such as input or album_art_editor APIs- | |
| 12 Obtain a write lock before accessing your file and release it when done. | |
| 13 If you want to keep an audio file open for an extended period of time and allow others to write to it- | |
| 14 Obtain a read lock, check is_release_requested() on it periodically; when it returns true, close the file, release the lock, obtain a new lock (which will block you until the peding write operation has completed), reopen the file and resume decoding where you left. | |
| 15 | |
| 16 Final note: | |
| 17 Majority of the fb2k components will never need this API. | |
| 18 If you carry out tag updates via metadb_io, the locking is already dealt with by fb2k core. | |
| 19 */ | |
| 20 | |
| 21 //! An instance of a file lock object. Use file_lock_manager to instantiate. | |
| 22 class NOVTABLE file_lock : public service_base { | |
| 23 public: | |
| 24 //! Returns whether we're blocking other attempts to access this file. A read lock does not block other read locks, but a write lock requires exclusive access.\n | |
| 25 //! Typically, time consuming read operations check this periodically and close the file / release the lock / reacquire the lock / reopen the file when signaled. | |
| 26 virtual bool is_release_requested() = 0; | |
| 27 | |
| 28 FB2K_MAKE_SERVICE_INTERFACE(file_lock, service_base); | |
| 29 }; | |
| 30 | |
| 31 typedef service_ptr_t<file_lock> file_lock_ptr; | |
| 32 | |
| 33 //! \since 1.5 | |
| 34 //! Modern version of file locking. \n | |
| 35 //! A read lock can be interrupted by a write lock request, from the thread that requested writing. \n | |
| 36 class NOVTABLE file_lock_interrupt : public service_base { | |
| 37 FB2K_MAKE_SERVICE_INTERFACE(file_lock_interrupt, service_base); | |
| 38 public: | |
| 39 //! Please note that interrupt() is called outside any sync scopes and may be called after lock reference has been released. \n | |
| 40 //! It is implementer's responsibility to safeguard against such. \n | |
| 41 //! The interrupt() function must *never* fail, unless aborted by calling context - which means that whoever asked for write access is aborting whatever they're doing. \n | |
| 42 //! This function may block for as long as it takes to release the owned resources, but must be able to abort cleanly if doing so. \n | |
| 43 //! If the function was aborted, it may be called again on the same object. \n | |
| 44 //! If the function succeeded, it will not be called again on the same object; the object will be released immediately after. | |
| 45 virtual void interrupt( abort_callback & aborter ) = 0; | |
| 46 | |
| 47 static file_lock_interrupt::ptr create( std::function< void (abort_callback&)> ); | |
| 48 }; | |
| 49 | |
| 50 //! Entry point class for obtaining file_lock objects. | |
| 51 class NOVTABLE file_lock_manager : public service_base { | |
| 52 public: | |
| 53 enum t_mode { | |
| 54 mode_read = 0, | |
| 55 mode_write | |
| 56 }; | |
| 57 //! Acquires a read or write lock for this file path. \n | |
| 58 //! If asked for read access, waits until nobody else holds a write lock for this path (but others may read at the same time). | |
| 59 //! If asked for write access, access until nobody else holds a read or write lock for this path. \n | |
| 60 //! The semantics are similar to those of blocking POSIX flock(). | |
| 61 virtual file_lock_ptr acquire(const char * p_path, t_mode p_mode, abort_callback & p_abort) = 0; | |
| 62 | |
| 63 //! Helper, calls acquire() with mode_read. | |
| 64 file_lock_ptr acquire_read(const char * p_path, abort_callback & p_abort) { return acquire(p_path, mode_read, p_abort); } | |
| 65 //! Helper, calls acquire() with mode_write. | |
| 66 file_lock_ptr acquire_write(const char * p_path, abort_callback & p_abort) { return acquire(p_path, mode_write, p_abort); } | |
| 67 | |
| 68 | |
| 69 FB2K_MAKE_SERVICE_COREAPI(file_lock_manager); | |
| 70 }; | |
| 71 | |
| 72 // \since 1.5 | |
| 73 class NOVTABLE file_lock_manager_v2 : public file_lock_manager { | |
| 74 FB2K_MAKE_SERVICE_COREAPI_EXTENSION( file_lock_manager_v2, file_lock_manager ); | |
| 75 public: | |
| 76 virtual fb2k::objRef acquire_read_v2(const char * p_path, file_lock_interrupt::ptr interruptHandler, abort_callback & p_abort) = 0; | |
| 77 }; |
