Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
5c9821d8
Commit
5c9821d8
authored
Nov 01, 2014
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
picture_pool: no longer muck with the reference counts, fix races
parent
85e5f7ca
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
59 additions
and
20 deletions
+59
-20
src/misc/picture_pool.c
src/misc/picture_pool.c
+59
-20
No files found.
src/misc/picture_pool.c
View file @
5c9821d8
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
struct
picture_gc_sys_t
{
struct
picture_gc_sys_t
{
picture_pool_t
*
pool
;
picture_pool_t
*
pool
;
picture_t
*
picture
;
picture_t
*
picture
;
bool
in_use
;
int64_t
tick
;
int64_t
tick
;
};
};
...
@@ -89,6 +90,11 @@ static void picture_pool_ReleasePicture(picture_t *picture)
...
@@ -89,6 +90,11 @@ static void picture_pool_ReleasePicture(picture_t *picture)
if
(
pool
->
pic_unlock
!=
NULL
)
if
(
pool
->
pic_unlock
!=
NULL
)
pool
->
pic_unlock
(
picture
);
pool
->
pic_unlock
(
picture
);
vlc_mutex_lock
(
&
pool
->
lock
);
assert
(
sys
->
in_use
);
sys
->
in_use
=
false
;
vlc_mutex_unlock
(
&
pool
->
lock
);
picture_pool_Release
(
pool
);
picture_pool_Release
(
pool
);
}
}
...
@@ -101,6 +107,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
...
@@ -101,6 +107,7 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
sys
->
pool
=
pool
;
sys
->
pool
=
pool
;
sys
->
picture
=
picture
;
sys
->
picture
=
picture
;
sys
->
in_use
=
false
;
sys
->
tick
=
0
;
sys
->
tick
=
0
;
picture_resource_t
res
=
{
picture_resource_t
res
=
{
...
@@ -231,62 +238,94 @@ void picture_pool_Delete(picture_pool_t *pool)
...
@@ -231,62 +238,94 @@ void picture_pool_Delete(picture_pool_t *pool)
picture_t
*
picture_pool_Get
(
picture_pool_t
*
pool
)
picture_t
*
picture_pool_Get
(
picture_pool_t
*
pool
)
{
{
vlc_mutex_lock
(
&
pool
->
lock
);
assert
(
pool
->
refs
>
0
);
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
picture_t
*
picture
=
pool
->
picture
[
i
];
picture_t
*
picture
=
pool
->
picture
[
i
];
uintptr_t
refs
=
0
;
picture_gc_sys_t
*
sys
=
picture
->
gc
.
p_sys
;
uint64_t
tick
;
if
(
!
atomic_compare_exchange_strong
(
&
picture
->
gc
.
refcount
,
&
refs
,
1
)
)
if
(
sys
->
in_use
)
continue
;
continue
;
pool
->
refs
++
;
tick
=
++
pool
->
tick
;
sys
->
in_use
=
true
;
vlc_mutex_unlock
(
&
pool
->
lock
);
if
(
pool
->
pic_lock
!=
NULL
&&
pool
->
pic_lock
(
picture
)
!=
0
)
{
if
(
pool
->
pic_lock
!=
NULL
&&
pool
->
pic_lock
(
picture
)
!=
0
)
{
atomic_store
(
&
picture
->
gc
.
refcount
,
0
);
vlc_mutex_lock
(
&
pool
->
lock
);
sys
->
in_use
=
false
;
pool
->
refs
--
;
vlc_mutex_unlock
(
&
pool
->
lock
);
continue
;
continue
;
}
}
vlc_mutex_lock
(
&
pool
->
lock
);
sys
->
tick
=
tick
;
pool
->
refs
++
;
picture
->
gc
.
p_sys
->
tick
=
pool
->
tick
++
;
vlc_mutex_unlock
(
&
pool
->
lock
);
assert
(
atomic_load
(
&
picture
->
gc
.
refcount
)
==
0
);
atomic_init
(
&
picture
->
gc
.
refcount
,
1
);
picture
->
p_next
=
NULL
;
picture
->
p_next
=
NULL
;
return
picture
;
return
picture
;
}
}
vlc_mutex_unlock
(
&
pool
->
lock
);
return
NULL
;
return
NULL
;
}
}
void
picture_pool_Reset
(
picture_pool_t
*
pool
)
void
picture_pool_Reset
(
picture_pool_t
*
pool
)
{
{
retry:
vlc_mutex_lock
(
&
pool
->
lock
);
assert
(
pool
->
refs
>
0
);
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
picture_t
*
picture
=
pool
->
picture
[
i
];
picture_t
*
picture
=
pool
->
picture
[
i
];
if
(
atomic_load
(
&
picture
->
gc
.
refcount
)
>
0
)
{
picture_gc_sys_t
*
sys
=
picture
->
gc
.
p_sys
;
if
(
pool
->
pic_unlock
!=
NULL
)
pool
->
pic_unlock
(
picture
);
if
(
sys
->
in_use
)
{
vlc_mutex_unlock
(
&
pool
->
lock
);
picture_Release
(
picture
);
goto
retry
;
}
}
atomic_store
(
&
picture
->
gc
.
refcount
,
0
);
}
}
vlc_mutex_unlock
(
&
pool
->
lock
);
}
}
void
picture_pool_NonEmpty
(
picture_pool_t
*
pool
)
void
picture_pool_NonEmpty
(
picture_pool_t
*
pool
)
{
{
picture_t
*
oldest
=
NULL
;
picture_t
*
oldest
=
NULL
;
uint64_t
tick
=
0
;
vlc_mutex_lock
(
&
pool
->
lock
);
assert
(
pool
->
refs
>
0
);
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
for
(
unsigned
i
=
0
;
i
<
pool
->
picture_count
;
i
++
)
{
picture_t
*
picture
=
pool
->
picture
[
i
];
picture_t
*
picture
=
pool
->
picture
[
i
];
if
(
atomic_load
(
&
picture
->
gc
.
refcount
)
==
0
)
picture_gc_sys_t
*
sys
=
picture
->
gc
.
p_sys
;
if
(
!
sys
->
in_use
)
{
vlc_mutex_unlock
(
&
pool
->
lock
);
return
;
/* Nothing to do */
return
;
/* Nothing to do */
}
if
(
oldest
==
NULL
||
picture
->
gc
.
p_sys
->
tick
<
oldest
->
gc
.
p_sys
->
tick
)
if
(
picture
->
gc
.
p_sys
->
tick
<
tick
)
{
oldest
=
picture
;
oldest
=
picture
;
tick
=
picture
->
gc
.
p_sys
->
tick
;
}
}
}
if
(
oldest
==
NULL
)
if
(
oldest
!=
NULL
)
{
return
;
/* Cannot fix! */
while
(
oldest
->
gc
.
p_sys
->
in_use
)
{
vlc_mutex_unlock
(
&
pool
->
lock
);
if
(
atomic_load
(
&
oldest
->
gc
.
refcount
)
>
0
)
{
picture_Release
(
oldest
);
if
(
pool
->
pic_unlock
!=
NULL
)
vlc_mutex_lock
(
&
pool
->
lock
);
pool
->
pic_unlock
(
oldest
);
}
}
}
atomic_store
(
&
oldest
->
gc
.
refcount
,
0
);
vlc_mutex_unlock
(
&
pool
->
lock
);
}
}
int
picture_pool_GetSize
(
picture_pool_t
*
pool
)
int
picture_pool_GetSize
(
picture_pool_t
*
pool
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment