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
35e2425f
Commit
35e2425f
authored
Jun 02, 2009
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Asynchronous timer API
parent
1074e9da
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
193 additions
and
0 deletions
+193
-0
include/vlc_threads.h
include/vlc_threads.h
+22
-0
src/libvlccore.sym
src/libvlccore.sym
+4
-0
src/misc/pthread.c
src/misc/pthread.c
+107
-0
src/misc/w32thread.c
src/misc/w32thread.c
+60
-0
No files found.
include/vlc_threads.h
View file @
35e2425f
...
...
@@ -108,6 +108,13 @@ typedef pthread_mutex_t vlc_mutex_t;
#define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
typedef
pthread_cond_t
vlc_cond_t
;
typedef
pthread_key_t
vlc_threadvar_t
;
typedef
struct
vlc_timer_t
vlc_timer_t
;
struct
vlc_timer_t
{
timer_t
handle
;
void
(
*
func
)
(
vlc_timer_t
*
,
void
*
);
void
*
data
;
};
#elif defined( WIN32 )
typedef
struct
...
...
@@ -129,6 +136,16 @@ typedef struct
typedef
HANDLE
vlc_cond_t
;
typedef
DWORD
vlc_threadvar_t
;
typedef
struct
vlc_timer_t
vlc_timer_t
;
struct
vlc_timer_t
{
HANDLE
handle
;
void
(
*
func
)
(
vlc_timer_t
*
,
void
*
);
void
*
data
;
unsigned
overrun
;
CRITICAL_SECTION
serializer
;
LONG
volatile
counter
;
};
#endif
...
...
@@ -164,6 +181,11 @@ VLC_EXPORT( void, vlc_cancel, (vlc_thread_t) );
VLC_EXPORT
(
void
,
vlc_join
,
(
vlc_thread_t
,
void
**
)
);
VLC_EXPORT
(
void
,
vlc_control_cancel
,
(
int
cmd
,
...));
VLC_EXPORT
(
int
,
vlc_timer_create
,
(
vlc_timer_t
*
,
void
(
*
)
(
vlc_timer_t
*
,
void
*
),
void
*
)
LIBVLC_USED
);
VLC_EXPORT
(
void
,
vlc_timer_destroy
,
(
vlc_timer_t
*
)
);
VLC_EXPORT
(
void
,
vlc_timer_schedule
,
(
vlc_timer_t
*
,
bool
,
mtime_t
,
mtime_t
)
);
VLC_EXPORT
(
unsigned
,
vlc_timer_getoverrun
,
(
const
vlc_timer_t
*
)
);
#ifndef LIBVLC_USE_PTHREAD_CANCEL
enum
{
VLC_DO_CANCEL
,
...
...
src/libvlccore.sym
View file @
35e2425f
...
...
@@ -522,6 +522,10 @@ vlc_threadvar_create
vlc_threadvar_delete
vlc_threadvar_get
vlc_threadvar_set
vlc_timer_create
vlc_timer_destroy
vlc_timer_getoverrun
vlc_timer_schedule
vlc_ureduce
VLC_Version
vlc_wclosedir
...
...
src/misc/pthread.c
View file @
35e2425f
...
...
@@ -583,3 +583,110 @@ void vlc_control_cancel (int cmd, ...)
(
void
)
cmd
;
assert
(
0
);
}
static
void
vlc_timer_do
(
union
sigval
val
)
{
vlc_timer_t
*
id
=
val
.
sival_ptr
;
id
->
func
(
id
,
id
->
data
);
}
/**
* Initializes an asynchronous timer.
* @warning Asynchronous timers are processed from an unspecified thread, and
* a timer is only serialized against itself.
*
* @param id pointer to timer to be initialized
* @param func function that the timer will call
* @param data parameter for the timer function
* @return 0 on success, a system error code otherwise.
*/
int
vlc_timer_create
(
vlc_timer_t
*
id
,
void
(
*
func
)
(
vlc_timer_t
*
,
void
*
),
void
*
data
)
{
struct
sigevent
ev
;
memset
(
&
ev
,
0
,
sizeof
(
ev
));
ev
.
sigev_notify
=
SIGEV_THREAD
;
ev
.
sigev_value
.
sival_ptr
=
id
;
ev
.
sigev_notify_function
=
vlc_timer_do
;
ev
.
sigev_notify_attributes
=
NULL
;
id
->
func
=
func
;
id
->
data
=
data
;
if
(
timer_create
(
CLOCK_MONOTONIC
,
&
ev
,
&
id
->
handle
))
return
errno
;
return
0
;
}
/**
* Destroys an initialized timer. If needed, the timer is first disarmed.
* This function is undefined if the specified timer is not initialized.
*
* @warning This function <b>must</b> be called before the timer data can be
* freed and before the timer callback function can be unloaded.
*
* @param timer to destroy
*/
void
vlc_timer_destroy
(
vlc_timer_t
*
id
)
{
int
val
=
timer_delete
(
id
->
handle
);
VLC_THREAD_ASSERT
(
"deleting timer"
);
}
/**
* Arm or disarm an initialized timer.
* This functions overrides any previous call to itself.
*
* @note A timer can fire later than requested due to system scheduling
* limitations. An interval timer can fail to trigger sometimes, either because
* the system is busy or suspended, or because a previous iteration of the
* timer is still running. See also vlc_timer_getoverrun().
*
* @param id initialized timer pointer
* @param absolute the timer value origin is the same as mdate() if true,
* the timer value is relative to now if false.
* @param value zero to disarm the timer, otherwise the initial time to wait
* before firing the timer.
* @param interval zero to fire the timer just once, otherwise the timer
* repetition interval.
*/
void
vlc_timer_schedule
(
vlc_timer_t
*
id
,
bool
absolute
,
mtime_t
value
,
mtime_t
interval
)
{
lldiv_t
vad
=
lldiv
(
value
,
CLOCK_FREQ
);
lldiv_t
itd
=
lldiv
(
interval
,
CLOCK_FREQ
);
struct
itimerspec
it
=
{
.
it_interval
=
{
.
tv_sec
=
itd
.
quot
,
.
tv_nsec
=
(
1000000000
/
CLOCK_FREQ
)
*
itd
.
rem
,
},
.
it_value
=
{
.
tv_sec
=
vad
.
quot
,
.
tv_nsec
=
(
1000000000
/
CLOCK_FREQ
)
*
vad
.
rem
,
},
};
int
flags
=
absolute
?
TIMER_ABSTIME
:
0
;
int
val
=
timer_settime
(
id
->
handle
,
flags
,
&
it
,
NULL
);
VLC_THREAD_ASSERT
(
"scheduling timer"
);
}
/**
* @param id initialized timer pointer
* @return the timer overrun counter, i.e. the number of times that the timer
* should have run but did not since the last actual run. If all is well, this
* is zero.
*/
unsigned
vlc_timer_getoverrun
(
const
vlc_timer_t
*
id
)
{
int
val
=
timer_getoverrun
(
id
->
handle
);
#ifndef NDEBUG
if
(
val
==
-
1
)
{
val
=
errno
;
VLC_THREAD_ASSERT
(
"fetching timer overrun counter"
);
}
#endif
return
val
;
}
src/misc/w32thread.c
View file @
35e2425f
...
...
@@ -510,3 +510,63 @@ void vlc_control_cancel (int cmd, ...)
}
va_end
(
ap
);
}
/*** Timers ***/
static
void
CALLBACK
vlc_timer_do
(
void
*
val
,
BOOLEAN
timeout
)
{
vlc_timer_t
*
id
=
val
;
assert
(
timeout
);
if
(
TryEnterCriticalSection
(
&
id
->
serializer
))
{
id
->
overrun
=
InterlockedExchange
(
&
id
->
counter
,
0
);
id
->
func
(
id
,
id
->
data
);
LeaveCriticalSection
(
&
id
->
serializer
);
}
else
/* Overrun */
InterlockedIncrement
(
&
id
->
counter
);
}
int
vlc_timer_create
(
vlc_timer_t
*
id
,
void
(
*
func
)
(
vlc_timer_t
*
,
void
*
),
void
*
data
)
{
id
->
func
=
func
;
id
->
data
=
data
;
id
->
overrun
=
0
;
id
->
handle
=
INVALID_HANDLE_VALUE
;
InitializeCriticalSection
(
&
id
->
serializer
);
return
0
;
}
void
vlc_timer_destroy
(
vlc_timer_t
*
id
)
{
if
(
id
->
handle
!=
INVALID_HANDLE_VALUE
)
DeleteTimerQueueTimer
(
NULL
,
id
->
handle
,
NULL
);
DeleteCriticalSection
(
&
id
->
serializer
);
}
void
vlc_timer_schedule
(
vlc_timer_t
*
id
,
bool
absolute
,
mtime_t
value
,
mtime_t
interval
)
{
if
(
id
->
handle
!=
INVALID_HANDLE_VALUE
)
{
DeleteTimerQueueTimer
(
NULL
,
id
->
handle
,
NULL
);
id
->
handle
=
INVALID_HANDLE_VALUE
;
}
if
(
value
==
0
)
return
;
/* Disarm */
if
(
absolute
)
value
-=
mdate
();
value
=
(
value
+
999
)
/
1000
;
interval
=
(
interval
+
999
)
/
1000
;
if
(
!
CreateTimerQueueTimer
(
&
id
->
handle
,
NULL
,
vlc_timer_do
,
id
,
value
,
interval
,
WT_EXECUTEDEFAULT
))
abort
();
}
unsigned
vlc_timer_getoverrun
(
const
vlc_timer_t
*
id
)
{
return
id
->
overrun
;
}
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