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
3cfff8db
Commit
3cfff8db
authored
Sep 11, 2012
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Write generic semaphore back-end and merge generic thread code
parent
4b95124b
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
144 additions
and
199 deletions
+144
-199
include/vlc_threads.h
include/vlc_threads.h
+16
-14
src/Makefile.am
src/Makefile.am
+0
-2
src/misc/rwlock.c
src/misc/rwlock.c
+0
-105
src/misc/threads.c
src/misc/threads.c
+128
-10
src/os2/thread.c
src/os2/thread.c
+0
-68
No files found.
include/vlc_threads.h
View file @
3cfff8db
...
...
@@ -158,8 +158,8 @@ typedef struct
}
vlc_cond_t
;
#define VLC_STATIC_COND { 0, 0 }
typedef
HANDLE
vlc_sem_t
;
typedef
struct
vlc_rwlock
vlc_rwlock_t
;
typedef
HANDLE
vlc_sem_t
;
#define LIBVLC_NEED_RWLOCK
typedef
struct
vlc_threadvar
*
vlc_threadvar_t
;
typedef
struct
vlc_timer
*
vlc_timer_t
;
...
...
@@ -188,27 +188,29 @@ typedef struct
}
vlc_cond_t
;
#define VLC_STATIC_COND { 0, 0 }
typedef
struct
{
HEV
hev
;
HMTX
wait_mutex
;
HMTX
count_mutex
;
int
count
;
}
vlc_sem_t
;
typedef
struct
vlc_rwlock
vlc_rwlock_t
;
#define LIBVLC_NEED_SEMAPHORE
#define LIBVLC_NEED_RWLOCK
typedef
struct
vlc_threadvar
*
vlc_threadvar_t
;
typedef
struct
vlc_timer
*
vlc_timer_t
;
#endif
#ifndef VLC_STATIC_RWLOCK
struct
vlc_rwlock
#ifdef LIBVLC_NEED_SEMAPHORE
typedef
struct
vlc_sem
{
vlc_mutex_t
lock
;
vlc_cond_t
wait
;
unsigned
value
;
}
vlc_sem_t
;
#endif
#ifdef LIBVLC_NEED_RWLOCK
typedef
struct
vlc_rwlock
{
vlc_mutex_t
mutex
;
vlc_cond_t
wait
;
long
state
;
};
}
vlc_rwlock_t
;
# define VLC_STATIC_RWLOCK { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0 }
#endif
...
...
src/Makefile.am
View file @
3cfff8db
...
...
@@ -269,7 +269,6 @@ SOURCES_libvlc_win32 = \
win32/dirs.c
\
win32/filesystem.c
\
win32/plugin.c
\
misc/rwlock.c
\
win32/thread.c
\
win32/specific.c
\
win32/winsock.c
\
...
...
@@ -288,7 +287,6 @@ SOURCES_libvlc_os2 = \
os2/dirs.c
\
os2/filesystem.c
\
os2/plugin.c
\
misc/rwlock.c
\
os2/thread.c
\
os2/specific.c
\
os2/rand.c
\
...
...
src/misc/rwlock.c
deleted
100644 → 0
View file @
4b95124b
/*****************************************************************************
* rwlock.h : generic back-end for LibVLC read/write locks
*****************************************************************************
* Copyright (C) 2009-2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
#include <vlc_common.h>
/* NOTE:
* lock->state is a signed long integer:
* - The sign bit is set when the lock is held for writing.
* - The other bits code the number of times the lock is held for reading.
* Consequently:
* - The value is negative if and only if the lock is held for writing.
* - The value is zero if and only if the lock is not held at all.
*/
#define READER_MASK LONG_MAX
#define WRITER_BIT LONG_MIN
void
vlc_rwlock_init
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_init
(
&
lock
->
mutex
);
vlc_cond_init
(
&
lock
->
wait
);
lock
->
state
=
0
;
}
void
vlc_rwlock_destroy
(
vlc_rwlock_t
*
lock
)
{
vlc_cond_destroy
(
&
lock
->
wait
);
vlc_mutex_destroy
(
&
lock
->
mutex
);
}
void
vlc_rwlock_rdlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Recursive read-locking is allowed.
* Ensure that there is no active writer. */
while
(
lock
->
state
<
0
)
{
assert
(
lock
->
state
==
WRITER_BIT
);
mutex_cleanup_push
(
&
lock
->
mutex
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
vlc_cleanup_pop
();
}
if
(
unlikely
(
lock
->
state
>=
READER_MASK
))
abort
();
/* An overflow is certainly a recursion bug. */
lock
->
state
++
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_wrlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Wait until nobody owns the lock in any way. */
while
(
lock
->
state
!=
0
)
{
mutex_cleanup_push
(
&
lock
->
mutex
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
vlc_cleanup_pop
();
}
lock
->
state
=
WRITER_BIT
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_unlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
if
(
lock
->
state
<
0
)
{
/* Write unlock */
assert
(
lock
->
state
==
WRITER_BIT
);
/* Let reader and writer compete. OS scheduler decides who wins. */
lock
->
state
=
0
;
vlc_cond_broadcast
(
&
lock
->
wait
);
}
else
{
/* Read unlock */
assert
(
lock
->
state
>
0
);
/* If there are no readers left, wake up one pending writer. */
if
(
--
lock
->
state
==
0
)
vlc_cond_signal
(
&
lock
->
wait
);
}
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
src/misc/threads.c
View file @
3cfff8db
/*****************************************************************************
* threads.c
: threads implementation for the VideoLAN clien
t
* threads.c
: LibVLC generic thread suppor
t
*****************************************************************************
* Copyright (C) 1999-2008 VLC authors and VideoLAN
* $Id$
*
* Authors: Jean-Marc Dressler <polux@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@netcourrier.com>
* Clément Sténac
* Rémi Denis-Courmont
* Copyright (C) 2009-2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
...
...
@@ -29,9 +22,10 @@
# include "config.h"
#endif
#include <vlc_common.h>
#include <assert.h>
#include <vlc_common.h>
/*** Global locks ***/
void
vlc_global_mutex
(
unsigned
n
,
bool
acquire
)
...
...
@@ -54,3 +48,127 @@ void vlc_global_mutex (unsigned n, bool acquire)
else
vlc_mutex_unlock
(
lock
);
}
#ifdef LIBVLC_NEED_RWLOCK
/*** Generic read/write locks ***/
#include <stdlib.h>
#include <limits.h>
/* NOTE:
* lock->state is a signed long integer:
* - The sign bit is set when the lock is held for writing.
* - The other bits code the number of times the lock is held for reading.
* Consequently:
* - The value is negative if and only if the lock is held for writing.
* - The value is zero if and only if the lock is not held at all.
*/
#define READER_MASK LONG_MAX
#define WRITER_BIT LONG_MIN
void
vlc_rwlock_init
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_init
(
&
lock
->
mutex
);
vlc_cond_init
(
&
lock
->
wait
);
lock
->
state
=
0
;
}
void
vlc_rwlock_destroy
(
vlc_rwlock_t
*
lock
)
{
vlc_cond_destroy
(
&
lock
->
wait
);
vlc_mutex_destroy
(
&
lock
->
mutex
);
}
void
vlc_rwlock_rdlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Recursive read-locking is allowed.
* Ensure that there is no active writer. */
while
(
lock
->
state
<
0
)
{
assert
(
lock
->
state
==
WRITER_BIT
);
mutex_cleanup_push
(
&
lock
->
mutex
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
vlc_cleanup_pop
();
}
if
(
unlikely
(
lock
->
state
>=
READER_MASK
))
abort
();
/* An overflow is certainly a recursion bug. */
lock
->
state
++
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_wrlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
/* Wait until nobody owns the lock in any way. */
while
(
lock
->
state
!=
0
)
{
mutex_cleanup_push
(
&
lock
->
mutex
);
vlc_cond_wait
(
&
lock
->
wait
,
&
lock
->
mutex
);
vlc_cleanup_pop
();
}
lock
->
state
=
WRITER_BIT
;
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
void
vlc_rwlock_unlock
(
vlc_rwlock_t
*
lock
)
{
vlc_mutex_lock
(
&
lock
->
mutex
);
if
(
lock
->
state
<
0
)
{
/* Write unlock */
assert
(
lock
->
state
==
WRITER_BIT
);
/* Let reader and writer compete. OS scheduler decides who wins. */
lock
->
state
=
0
;
vlc_cond_broadcast
(
&
lock
->
wait
);
}
else
{
/* Read unlock */
assert
(
lock
->
state
>
0
);
/* If there are no readers left, wake up one pending writer. */
if
(
--
lock
->
state
==
0
)
vlc_cond_signal
(
&
lock
->
wait
);
}
vlc_mutex_unlock
(
&
lock
->
mutex
);
}
#endif
/* LIBVLC_NEED_RWLOCK */
#ifdef LIBVLC_NEED_SEMAPHORE
/*** Generic semaphores ***/
#include <limits.h>
#include <errno.h>
void
vlc_sem_init
(
vlc_sem_t
*
sem
,
unsigned
value
)
{
vlc_mutex_init
(
&
sem
->
lock
);
vlc_cond_init
(
&
sem
->
wait
);
sem
->
value
=
value
;
}
void
vlc_sem_destroy
(
vlc_sem_t
*
sem
)
{
vlc_cond_destroy
(
&
sem
->
wait
);
vlc_mutex_destroy
(
&
sem
->
lock
);
}
int
vlc_sem_post
(
vlc_sem_t
*
sem
)
{
int
ret
=
0
;
vlc_mutex_lock
(
&
sem
->
lock
);
if
(
likely
(
sem
->
value
!=
UINT_MAX
))
sem
->
value
++
;
else
ret
=
EOVERFLOW
;
vlc_mutex_unlock
(
&
sem
->
lock
);
vlc_cond_signal
(
&
sem
->
wait
);
return
ret
;
}
void
vlc_sem_wait
(
vlc_sem_t
*
sem
)
{
vlc_mutex_lock
(
&
sem
->
lock
);
while
(
!
sem
->
value
)
vlc_cond_wait
(
&
sem
->
wait
,
&
sem
->
lock
);
sem
->
value
--
;
vlc_mutex_unlock
(
&
sem
->
lock
);
}
#endif
/* LIBVLC_NEED_SEMAPHORE */
src/os2/thread.c
View file @
3cfff8db
...
...
@@ -360,74 +360,6 @@ int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
return
rc
?
ETIMEDOUT
:
0
;
}
/*** Semaphore ***/
void
vlc_sem_init
(
vlc_sem_t
*
sem
,
unsigned
value
)
{
if
(
DosCreateEventSem
(
NULL
,
&
sem
->
hev
,
0
,
value
>
0
?
TRUE
:
FALSE
))
abort
();
if
(
DosCreateMutexSem
(
NULL
,
&
sem
->
wait_mutex
,
0
,
FALSE
))
abort
();
if
(
DosCreateMutexSem
(
NULL
,
&
sem
->
count_mutex
,
0
,
FALSE
))
abort
();
sem
->
count
=
value
;
}
void
vlc_sem_destroy
(
vlc_sem_t
*
sem
)
{
DosCloseEventSem
(
sem
->
hev
);
DosCloseMutexSem
(
sem
->
wait_mutex
);
DosCloseMutexSem
(
sem
->
count_mutex
);
}
int
vlc_sem_post
(
vlc_sem_t
*
sem
)
{
DosRequestMutexSem
(
sem
->
count_mutex
,
SEM_INDEFINITE_WAIT
);
if
(
sem
->
count
<
0x7FFFFFFF
)
{
sem
->
count
++
;
DosPostEventSem
(
sem
->
hev
);
}
DosReleaseMutexSem
(
sem
->
count_mutex
);
return
0
;
/* FIXME */
}
void
vlc_sem_wait
(
vlc_sem_t
*
sem
)
{
ULONG
rc
;
do
{
vlc_testcancel
();
DosRequestMutexSem
(
sem
->
wait_mutex
,
SEM_INDEFINITE_WAIT
);
rc
=
vlc_WaitForSingleObject
(
sem
->
hev
,
SEM_INDEFINITE_WAIT
);
if
(
!
rc
)
{
DosRequestMutexSem
(
sem
->
count_mutex
,
SEM_INDEFINITE_WAIT
);
sem
->
count
--
;
if
(
sem
->
count
==
0
)
{
ULONG
ulPost
;
DosResetEventSem
(
sem
->
hev
,
&
ulPost
);
}
DosReleaseMutexSem
(
sem
->
count_mutex
);
}
DosReleaseMutexSem
(
sem
->
wait_mutex
);
}
while
(
rc
==
ERROR_INTERRUPT
);
}
/*** Thread-specific variables (TLS) ***/
struct
vlc_threadvar
{
...
...
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