avcodec/utils: av_lockmgr_register defines behavior on failure.

The register function now specifies that the user callback should
leave things in the same state that it found them on failure but
that failure to destroy is ignored by the library.  The register
function is now explicit about its behavior on failure
(it unregisters the previous callback and destroys all mutex).

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Manfred Georg
2014-10-02 11:54:31 -07:00
committed by Michael Niedermayer
parent cdd6f059a6
commit a950edb472
2 changed files with 41 additions and 21 deletions

View File

@@ -3474,22 +3474,32 @@ AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel)
int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op))
{
if (lockmgr_cb) {
if (lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY))
return -1;
if (lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY))
return -1;
codec_mutex = NULL;
// There is no good way to rollback a failure to destroy the
// mutex, so we ignore failures.
lockmgr_cb(&codec_mutex, AV_LOCK_DESTROY);
lockmgr_cb(&avformat_mutex, AV_LOCK_DESTROY);
lockmgr_cb = NULL;
codec_mutex = NULL;
avformat_mutex = NULL;
}
lockmgr_cb = cb;
if (lockmgr_cb) {
if (lockmgr_cb(&codec_mutex, AV_LOCK_CREATE))
return -1;
if (lockmgr_cb(&avformat_mutex, AV_LOCK_CREATE))
return -1;
if (cb) {
void *new_codec_mutex = NULL;
void *new_avformat_mutex = NULL;
int err;
if (err = cb(&new_codec_mutex, AV_LOCK_CREATE)) {
return err > 0 ? AVERROR_EXTERNAL : err;
}
if (err = cb(&new_avformat_mutex, AV_LOCK_CREATE)) {
// Ignore failures to destroy the newly created mutex.
cb(&new_codec_mutex, AV_LOCK_DESTROY);
return err > 0 ? AVERROR_EXTERNAL : err;
}
lockmgr_cb = cb;
codec_mutex = new_codec_mutex;
avformat_mutex = new_avformat_mutex;
}
return 0;
}