diff options
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r-- | libavcodec/utils.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c index a47207610d..94eca9bd11 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -2318,20 +2318,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; + // 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; + } + + 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_UNKNOWN : 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_UNKNOWN : err; + } + lockmgr_cb = cb; + codec_mutex = new_codec_mutex; + avformat_mutex = new_avformat_mutex; } - 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; - } return 0; } |