latest SDK
This commit is contained in:
77
foobar2000/SDK/file_lock_manager.h
Normal file
77
foobar2000/SDK/file_lock_manager.h
Normal file
@@ -0,0 +1,77 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
File lock management API
|
||||
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.
|
||||
The semantics are similar to those of blocking POSIX flock().
|
||||
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.
|
||||
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.
|
||||
|
||||
Usage examples:
|
||||
If you want to write tags to an audio file, using low level methods such as input or album_art_editor APIs-
|
||||
Obtain a write lock before accessing your file and release it when done.
|
||||
If you want to keep an audio file open for an extended period of time and allow others to write to it-
|
||||
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.
|
||||
|
||||
Final note:
|
||||
Majority of the fb2k components will never need this API.
|
||||
If you carry out tag updates via metadb_io, the locking is already dealt with by fb2k core.
|
||||
*/
|
||||
|
||||
//! An instance of a file lock object. Use file_lock_manager to instantiate.
|
||||
class NOVTABLE file_lock : public service_base {
|
||||
public:
|
||||
//! 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
|
||||
//! Typically, time consuming read operations check this periodically and close the file / release the lock / reacquire the lock / reopen the file when signaled.
|
||||
virtual bool is_release_requested() = 0;
|
||||
|
||||
FB2K_MAKE_SERVICE_INTERFACE(file_lock, service_base);
|
||||
};
|
||||
|
||||
typedef service_ptr_t<file_lock> file_lock_ptr;
|
||||
|
||||
//! \since 1.5
|
||||
//! Modern version of file locking. \n
|
||||
//! A read lock can be interrupted by a write lock request, from the thread that requested writing. \n
|
||||
class NOVTABLE file_lock_interrupt : public service_base {
|
||||
FB2K_MAKE_SERVICE_INTERFACE(file_lock_interrupt, service_base);
|
||||
public:
|
||||
//! Please note that interrupt() is called outside any sync scopes and may be called after lock reference has been released. \n
|
||||
//! It is implementer's responsibility to safeguard against such. \n
|
||||
//! 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
|
||||
//! 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
|
||||
//! If the function was aborted, it may be called again on the same object. \n
|
||||
//! If the function succeeded, it will not be called again on the same object; the object will be released immediately after.
|
||||
virtual void interrupt( abort_callback & aborter ) = 0;
|
||||
|
||||
static file_lock_interrupt::ptr create( std::function< void (abort_callback&)> );
|
||||
};
|
||||
|
||||
//! Entry point class for obtaining file_lock objects.
|
||||
class NOVTABLE file_lock_manager : public service_base {
|
||||
public:
|
||||
enum t_mode {
|
||||
mode_read = 0,
|
||||
mode_write
|
||||
};
|
||||
//! Acquires a read or write lock for this file path. \n
|
||||
//! If asked for read access, waits until nobody else holds a write lock for this path (but others may read at the same time).
|
||||
//! If asked for write access, access until nobody else holds a read or write lock for this path. \n
|
||||
//! The semantics are similar to those of blocking POSIX flock().
|
||||
virtual file_lock_ptr acquire(const char * p_path, t_mode p_mode, abort_callback & p_abort) = 0;
|
||||
|
||||
//! Helper, calls acquire() with mode_read.
|
||||
file_lock_ptr acquire_read(const char * p_path, abort_callback & p_abort) { return acquire(p_path, mode_read, p_abort); }
|
||||
//! Helper, calls acquire() with mode_write.
|
||||
file_lock_ptr acquire_write(const char * p_path, abort_callback & p_abort) { return acquire(p_path, mode_write, p_abort); }
|
||||
|
||||
|
||||
FB2K_MAKE_SERVICE_COREAPI(file_lock_manager);
|
||||
};
|
||||
|
||||
// \since 1.5
|
||||
class NOVTABLE file_lock_manager_v2 : public file_lock_manager {
|
||||
FB2K_MAKE_SERVICE_COREAPI_EXTENSION( file_lock_manager_v2, file_lock_manager );
|
||||
public:
|
||||
virtual fb2k::objRef acquire_read_v2(const char * p_path, file_lock_interrupt::ptr interruptHandler, abort_callback & p_abort) = 0;
|
||||
};
|
||||
Reference in New Issue
Block a user