aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/utils.c
diff options
context:
space:
mode:
authorManfred Georg <mgeorg@google.com>2014-10-02 11:54:31 -0700
committerMichael Niedermayer <michaelni@gmx.at>2014-10-02 21:18:49 +0200
commita950edb472e8823e34832c7313ba447b2db76f27 (patch)
tree0124a1a0a9a12cc7554e713a269f355e879a01db /libavcodec/utils.c
parentcdd6f059a65f28ff7a18ccf1194e9554adad1a1b (diff)
downloadffmpeg-a950edb472e8823e34832c7313ba447b2db76f27.tar.gz
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>
Diffstat (limited to 'libavcodec/utils.c')
-rw-r--r--libavcodec/utils.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index ee9e24805b..d4f5532067 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -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;
}