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
cba8b415
Commit
cba8b415
authored
Jun 02, 2009
by
Pierre d'Herbemont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libvlc: Allow event to be dispatched asynchronously.
parent
c9a2b2df
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
459 additions
and
106 deletions
+459
-106
src/Makefile.am
src/Makefile.am
+2
-0
src/control/event.c
src/control/event.c
+102
-44
src/control/event_async.c
src/control/event_async.c
+237
-0
src/control/event_internal.h
src/control/event_internal.h
+113
-0
src/control/libvlc_internal.h
src/control/libvlc_internal.h
+5
-62
No files found.
src/Makefile.am
View file @
cba8b415
...
@@ -427,6 +427,7 @@ SOURCES_libvlc = \
...
@@ -427,6 +427,7 @@ SOURCES_libvlc = \
SOURCES_libvlc_control
=
\
SOURCES_libvlc_control
=
\
control/libvlc_internal.h
\
control/libvlc_internal.h
\
control/event_internal.h
\
control/media_internal.h
\
control/media_internal.h
\
control/media_list_internal.h
\
control/media_list_internal.h
\
control/media_list_view_internal.h
\
control/media_list_view_internal.h
\
...
@@ -438,6 +439,7 @@ SOURCES_libvlc_control = \
...
@@ -438,6 +439,7 @@ SOURCES_libvlc_control = \
control/video.c
\
control/video.c
\
control/audio.c
\
control/audio.c
\
control/event.c
\
control/event.c
\
control/event_async.c
\
control/flat_media_list_view.c
\
control/flat_media_list_view.c
\
control/hierarchical_media_list_view.c
\
control/hierarchical_media_list_view.c
\
control/hierarchical_node_media_list_view.c
\
control/hierarchical_node_media_list_view.c
\
...
...
src/control/event.c
View file @
cba8b415
...
@@ -22,23 +22,22 @@
...
@@ -22,23 +22,22 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
*****************************************************************************/
#include "libvlc_internal.h"
#include <vlc/libvlc.h>
#include <vlc/libvlc.h>
#include <vlc_playlist.h>
#include "libvlc_internal.h"
#include "event_internal.h"
typedef
struct
libvlc_event_listeners_group_t
{
libvlc_event_type_t
event_type
;
vlc_array_t
listeners
;
bool
b_sublistener_removed
;
}
libvlc_event_listeners_group_t
;
/*
/*
* Private functions
* Private functions
*/
*/
static
bool
listeners_are_equal
(
libvlc_event_listener_t
*
listener1
,
libvlc_event_listener_t
*
listener2
)
{
return
listener1
->
event_type
==
listener2
->
event_type
&&
listener1
->
pf_callback
==
listener2
->
pf_callback
&&
listener1
->
p_user_data
==
listener2
->
p_user_data
;
}
static
bool
static
bool
group_contains_listener
(
libvlc_event_listeners_group_t
*
group
,
group_contains_listener
(
libvlc_event_listeners_group_t
*
group
,
libvlc_event_listener_t
*
searched_listener
)
libvlc_event_listener_t
*
searched_listener
)
...
@@ -75,7 +74,10 @@ libvlc_event_manager_new( void * p_obj, libvlc_instance_t * p_libvlc_inst,
...
@@ -75,7 +74,10 @@ libvlc_event_manager_new( void * p_obj, libvlc_instance_t * p_libvlc_inst,
}
}
p_em
->
p_obj
=
p_obj
;
p_em
->
p_obj
=
p_obj
;
p_em
->
p_obj
=
p_obj
;
p_em
->
async_event_queue
=
NULL
;
p_em
->
p_libvlc_instance
=
p_libvlc_inst
;
p_em
->
p_libvlc_instance
=
p_libvlc_inst
;
libvlc_retain
(
p_libvlc_inst
);
libvlc_retain
(
p_libvlc_inst
);
vlc_array_init
(
&
p_em
->
listeners_groups
);
vlc_array_init
(
&
p_em
->
listeners_groups
);
vlc_mutex_init
(
&
p_em
->
object_lock
);
vlc_mutex_init
(
&
p_em
->
object_lock
);
...
@@ -93,6 +95,8 @@ void libvlc_event_manager_release( libvlc_event_manager_t * p_em )
...
@@ -93,6 +95,8 @@ void libvlc_event_manager_release( libvlc_event_manager_t * p_em )
libvlc_event_listeners_group_t
*
p_lg
;
libvlc_event_listeners_group_t
*
p_lg
;
int
i
,
j
;
int
i
,
j
;
libvlc_event_async_fini
(
p_em
);
vlc_mutex_destroy
(
&
p_em
->
event_sending_lock
);
vlc_mutex_destroy
(
&
p_em
->
event_sending_lock
);
vlc_mutex_destroy
(
&
p_em
->
object_lock
);
vlc_mutex_destroy
(
&
p_em
->
object_lock
);
...
@@ -165,7 +169,8 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
...
@@ -165,7 +169,8 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
if
(
vlc_array_count
(
&
listeners_group
->
listeners
)
<=
0
)
if
(
vlc_array_count
(
&
listeners_group
->
listeners
)
<=
0
)
break
;
break
;
/* Cache a copy of the listener to avoid locking issues */
/* Cache a copy of the listener to avoid locking issues,
* and allow that edition of listeners during callbacks will garantee immediate effect. */
i_cached_listeners
=
vlc_array_count
(
&
listeners_group
->
listeners
);
i_cached_listeners
=
vlc_array_count
(
&
listeners_group
->
listeners
);
array_listeners_cached
=
malloc
(
sizeof
(
libvlc_event_listener_t
)
*
(
i_cached_listeners
));
array_listeners_cached
=
malloc
(
sizeof
(
libvlc_event_listener_t
)
*
(
i_cached_listeners
));
if
(
!
array_listeners_cached
)
if
(
!
array_listeners_cached
)
...
@@ -200,22 +205,32 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
...
@@ -200,22 +205,32 @@ void libvlc_event_send( libvlc_event_manager_t * p_em,
listeners_group
->
b_sublistener_removed
=
false
;
listeners_group
->
b_sublistener_removed
=
false
;
for
(
i
=
0
;
i
<
i_cached_listeners
;
i
++
)
for
(
i
=
0
;
i
<
i_cached_listeners
;
i
++
)
{
{
if
(
listeners_group
->
b_sublistener_removed
)
if
(
listener_cached
->
is_asynchronous
)
{
{
/* If a callback was removed, this gets called */
/* The listener wants not to block the emitter during event callback */
bool
valid_listener
;
libvlc_event_async_dispatch
(
p_em
,
listener_cached
,
p_event
);
vlc_mutex_lock
(
&
p_em
->
object_lock
);
}
valid_listener
=
group_contains_listener
(
listeners_group
,
listener_cached
);
else
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
{
if
(
!
valid_listener
)
/* The listener wants to block the emitter during event callback */
listener_cached
->
pf_callback
(
p_event
,
listener_cached
->
p_user_data
);
listener_cached
++
;
if
(
listeners_group
->
b_sublistener_removed
)
{
{
listener_cached
++
;
/* If a callback was removed, this gets called */
continue
;
bool
valid_listener
;
}
vlc_mutex_lock
(
&
p_em
->
object_lock
);
valid_listener
=
group_contains_listener
(
listeners_group
,
listener_cached
);
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
if
(
!
valid_listener
)
{
listener_cached
++
;
continue
;
}
}
}
}
listener_cached
->
pf_callback
(
p_event
,
listener_cached
->
p_user_data
);
listener_cached
++
;
}
}
vlc_mutex_unlock
(
&
p_em
->
event_sending_lock
);
vlc_mutex_unlock
(
&
p_em
->
event_sending_lock
);
...
@@ -287,31 +302,34 @@ const char * libvlc_event_type_name( libvlc_event_type_t event_type )
...
@@ -287,31 +302,34 @@ const char * libvlc_event_type_name( libvlc_event_type_t event_type )
}
}
/**************************************************************************
/**************************************************************************
*
libvlc_event_attach (public
) :
*
event_attach (internal
) :
*
*
* Add a callback for an event.
* Add a callback for an event.
**************************************************************************/
**************************************************************************/
void
libvlc_event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
static
libvlc_event_type_t
event_type
,
void
event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_callback_t
pf_callback
,
libvlc_event_type_t
event_type
,
void
*
p_user_data
,
libvlc_callback_t
pf_callback
,
libvlc_exception_t
*
p_e
)
void
*
p_user_data
,
bool
is_asynchronous
,
libvlc_exception_t
*
p_e
)
{
{
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listener_t
*
listener
;
libvlc_event_listener_t
*
listener
;
int
i
;
int
i
;
listener
=
malloc
(
sizeof
(
libvlc_event_listener_t
));
listener
=
malloc
(
sizeof
(
libvlc_event_listener_t
));
if
(
!
listener
)
if
(
!
listener
)
{
{
libvlc_exception_raise
(
p_e
,
"No Memory left"
);
libvlc_exception_raise
(
p_e
,
"No Memory left"
);
return
;
return
;
}
}
listener
->
event_type
=
event_type
;
listener
->
event_type
=
event_type
;
listener
->
p_user_data
=
p_user_data
;
listener
->
p_user_data
=
p_user_data
;
listener
->
pf_callback
=
pf_callback
;
listener
->
pf_callback
=
pf_callback
;
listener
->
is_asynchronous
=
is_asynchronous
;
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
{
{
...
@@ -324,11 +342,39 @@ void libvlc_event_attach( libvlc_event_manager_t * p_event_manager,
...
@@ -324,11 +342,39 @@ void libvlc_event_attach( libvlc_event_manager_t * p_event_manager,
}
}
}
}
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
free
(
listener
);
free
(
listener
);
libvlc_exception_raise
(
p_e
,
libvlc_exception_raise
(
p_e
,
"This object event manager doesn't know about '%s' events"
,
"This object event manager doesn't know about '%s' events"
,
libvlc_event_type_name
(
event_type
));
libvlc_event_type_name
(
event_type
));
}
/**************************************************************************
* libvlc_event_attach (public) :
*
* Add a callback for an event.
**************************************************************************/
void
libvlc_event_attach
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
)
{
event_attach
(
p_event_manager
,
event_type
,
pf_callback
,
p_user_data
,
false
/* synchronous */
,
p_e
);
}
/**************************************************************************
* libvlc_event_attach (public) :
*
* Add a callback for an event.
**************************************************************************/
void
libvlc_event_attach_async
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
)
{
event_attach
(
p_event_manager
,
event_type
,
pf_callback
,
p_user_data
,
true
/* asynchronous */
,
p_e
);
}
}
/**************************************************************************
/**************************************************************************
...
@@ -345,7 +391,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
...
@@ -345,7 +391,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listeners_group_t
*
listeners_group
;
libvlc_event_listener_t
*
listener
;
libvlc_event_listener_t
*
listener
;
int
i
,
j
;
int
i
,
j
;
bool
found
=
false
;
vlc_mutex_lock
(
&
p_event_manager
->
event_sending_lock
);
vlc_mutex_lock
(
&
p_event_manager
->
event_sending_lock
);
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_lock
(
&
p_event_manager
->
object_lock
);
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
for
(
i
=
0
;
i
<
vlc_array_count
(
&
p_event_manager
->
listeners_groups
);
i
++
)
...
@@ -368,9 +415,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
...
@@ -368,9 +415,8 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
free
(
listener
);
free
(
listener
);
vlc_array_remove
(
&
listeners_group
->
listeners
,
j
);
vlc_array_remove
(
&
listeners_group
->
listeners
,
j
);
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
found
=
true
;
vlc_mutex_unlock
(
&
p_event_manager
->
event_sending_lock
);
break
;
return
;
}
}
}
}
}
}
...
@@ -378,7 +424,19 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
...
@@ -378,7 +424,19 @@ void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
object_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
event_sending_lock
);
vlc_mutex_unlock
(
&
p_event_manager
->
event_sending_lock
);
libvlc_exception_raise
(
p_e
,
/* Now make sure any pending async event won't get fired after that point */
"This object event manager doesn't know about '%s,%p,%p' event observer"
,
libvlc_event_listener_t
listener_to_remove
;
libvlc_event_type_name
(
event_type
),
pf_callback
,
p_user_data
);
listener_to_remove
.
event_type
=
event_type
;
listener_to_remove
.
pf_callback
=
pf_callback
;
listener_to_remove
.
p_user_data
=
p_user_data
;
listener_to_remove
.
is_asynchronous
=
true
;
libvlc_event_async_ensure_listener_removal
(
p_event_manager
,
&
listener_to_remove
);
if
(
!
found
)
{
libvlc_exception_raise
(
p_e
,
"This object event manager doesn't know about '%s,%p,%p' event observer"
,
libvlc_event_type_name
(
event_type
),
pf_callback
,
p_user_data
);
}
}
}
src/control/event_async.c
0 → 100644
View file @
cba8b415
/*****************************************************************************
* event.c: New libvlc event control API
*****************************************************************************
* Copyright (C) 2007 the VideoLAN team
* $Id $
*
* Authors: Filippo Carone <filippo@carone.org>
* Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
#include <vlc/libvlc.h>
#include "libvlc_internal.h"
#include "event_internal.h"
struct
queue_elmt
{
libvlc_event_listener_t
listener
;
libvlc_event_t
event
;
struct
queue_elmt
*
next
;
};
struct
libvlc_event_async_queue
{
struct
queue_elmt
*
elements
;
vlc_mutex_t
lock
;
vlc_cond_t
signal
;
vlc_thread_t
thread
;
};
/*
* Utilities
*/
static
void
*
event_async_loop
(
void
*
arg
);
static
inline
struct
libvlc_event_async_queue
*
queue
(
libvlc_event_manager_t
*
p_em
)
{
return
p_em
->
async_event_queue
;
}
static
inline
bool
is_queue_initialized
(
libvlc_event_manager_t
*
p_em
)
{
return
queue
(
p_em
)
!=
NULL
;
}
/* Lock must be held */
static
void
push
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
#ifndef NDEBUG
static
const
long
MaxQueuedItem
=
300000
;
long
count
=
0
;
#endif
struct
queue_elmt
*
elmt
=
malloc
(
sizeof
(
struct
queue_elmt
));
elmt
->
listener
=
*
listener
;
elmt
->
event
=
*
event
;
elmt
->
next
=
NULL
;
/* Append to the end of the queue */
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
if
(
!
iter
)
{
queue
(
p_em
)
->
elements
=
elmt
;
return
;
}
while
(
iter
->
next
)
{
iter
=
iter
->
next
;
#ifndef NDEBUG
if
(
count
++
>
MaxQueuedItem
)
{
fprintf
(
stderr
,
"Warning: libvlc event overflow.
\n
"
);
abort
();
}
#endif
}
iter
->
next
=
elmt
;
}
/* Lock must be held */
static
bool
pop
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
if
(
!
queue
(
p_em
)
->
elements
)
return
false
;
/* No elements */
*
listener
=
queue
(
p_em
)
->
elements
->
listener
;
*
event
=
queue
(
p_em
)
->
elements
->
event
;
struct
queue_elmt
*
elmt
=
queue
(
p_em
)
->
elements
;
queue
(
p_em
)
->
elements
=
elmt
->
next
;
free
(
elmt
);
return
true
;
}
/* Lock must be held */
static
void
pop_listener
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
)
{
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
struct
queue_elmt
*
prev
=
NULL
;
while
(
iter
)
{
if
(
listeners_are_equal
(
&
iter
->
listener
,
listener
))
{
if
(
!
prev
)
queue
(
p_em
)
->
elements
=
iter
->
next
;
else
prev
->
next
=
iter
->
next
;
free
(
iter
);
}
prev
=
iter
;
iter
=
iter
->
next
;
}
}
/**************************************************************************
* libvlc_event_async_fini (internal) :
*
* Destroy what might have been created by.
**************************************************************************/
void
libvlc_event_async_fini
(
libvlc_event_manager_t
*
p_em
)
{
if
(
!
is_queue_initialized
(
p_em
))
return
;
vlc_thread_t
thread
=
queue
(
p_em
)
->
thread
;
if
(
thread
)
{
vlc_cancel
(
thread
);
vlc_join
(
thread
,
NULL
);
}
vlc_mutex_destroy
(
&
queue
(
p_em
)
->
lock
);
vlc_cond_destroy
(
&
queue
(
p_em
)
->
signal
);
struct
queue_elmt
*
iter
=
queue
(
p_em
)
->
elements
;
while
(
iter
)
{
struct
queue_elmt
*
elemt_to_delete
=
iter
;
iter
=
iter
->
next
;
free
(
elemt_to_delete
);
}
free
(
queue
(
p_em
));
}
/**************************************************************************
* libvlc_event_async_init (private) :
*
* Destroy what might have been created by.
**************************************************************************/
static
void
libvlc_event_async_init
(
libvlc_event_manager_t
*
p_em
)
{
p_em
->
async_event_queue
=
calloc
(
1
,
sizeof
(
struct
libvlc_event_async_queue
));
int
error
=
vlc_clone
(
&
queue
(
p_em
)
->
thread
,
event_async_loop
,
p_em
,
VLC_THREAD_PRIORITY_LOW
);
if
(
error
)
{
free
(
p_em
->
async_event_queue
);
p_em
->
async_event_queue
=
NULL
;
return
;
}
vlc_mutex_init_recursive
(
&
queue
(
p_em
)
->
lock
);
// Beware, this is re-entrant
vlc_cond_init
(
&
queue
(
p_em
)
->
signal
);
}
/**************************************************************************
* libvlc_event_async_ensure_listener_removal (internal) :
*
* Make sure no more message will be issued to the listener.
**************************************************************************/
void
libvlc_event_async_ensure_listener_removal
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
)
{
if
(
!
is_queue_initialized
(
p_em
))
return
;
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
pop_listener
(
p_em
,
listener
);
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
}
/**************************************************************************
* libvlc_event_async_dispatch (internal) :
*
* Send an event in an asynchronous way.
**************************************************************************/
void
libvlc_event_async_dispatch
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
)
{
// We do a lazy init here, to prevent constructing the thread when not needed.
vlc_mutex_lock
(
&
p_em
->
object_lock
);
if
(
!
queue
(
p_em
))
libvlc_event_async_init
(
p_em
);
vlc_mutex_unlock
(
&
p_em
->
object_lock
);
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
push
(
p_em
,
listener
,
event
);
vlc_cond_signal
(
&
queue
(
p_em
)
->
signal
);
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
}
/**************************************************************************
* event_async_loop (private) :
*
* Send queued events.
**************************************************************************/
static
void
*
event_async_loop
(
void
*
arg
)
{
libvlc_event_manager_t
*
p_em
=
arg
;
libvlc_event_listener_t
listener
;
libvlc_event_t
event
;
vlc_mutex_lock
(
&
queue
(
p_em
)
->
lock
);
vlc_cleanup_push
(
vlc_cleanup_lock
,
&
queue
(
p_em
)
->
lock
);
while
(
true
)
{
int
has_listener
=
pop
(
p_em
,
&
listener
,
&
event
);
if
(
has_listener
)
listener
.
pf_callback
(
&
event
,
listener
.
p_user_data
);
// This might edit the queue, ->lock is recursive
else
vlc_cond_wait
(
&
queue
(
p_em
)
->
signal
,
&
queue
(
p_em
)
->
lock
);
}
vlc_cleanup_pop
();
vlc_mutex_unlock
(
&
queue
(
p_em
)
->
lock
);
return
NULL
;
}
src/control/event_internal.h
0 → 100644
View file @
cba8b415
/*****************************************************************************
* libvlc_internal.h : Definition of opaque structures for libvlc exported API
* Also contains some internal utility functions
*****************************************************************************
* Copyright (C) 2005-2009 the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU 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.
*****************************************************************************/
#ifndef _LIBVLC_EVENT_H
#define _LIBVLC_EVENT_H 1
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc/libvlc_structures.h>
#include <vlc/libvlc.h>
#include <vlc/libvlc_events.h>
#include <vlc_common.h>
/*
* Event Handling
*/
/* Example usage
*
* struct libvlc_cool_object_t
* {
* ...
* libvlc_event_manager_t * p_event_manager;
* ...
* }
*
* libvlc_my_cool_object_new()
* {
* ...
* p_self->p_event_manager = libvlc_event_manager_new( p_self,
* p_self->p_libvlc_instance, p_e);
* libvlc_event_manager_register_event_type(p_self->p_event_manager,
* libvlc_MyCoolObjectDidSomething, p_e)
* ...
* }
*
* libvlc_my_cool_object_release()
* {
* ...
* libvlc_event_manager_release( p_self->p_event_manager );
* ...
* }
*
* libvlc_my_cool_object_do_something()
* {
* ...
* libvlc_event_t event;
* event.type = libvlc_MyCoolObjectDidSomething;
* event.u.my_cool_object_did_something.what_it_did = kSomething;
* libvlc_event_send( p_self->p_event_manager, &event );
* }
* */
typedef
struct
libvlc_event_listener_t
{
libvlc_event_type_t
event_type
;
void
*
p_user_data
;
libvlc_callback_t
pf_callback
;
bool
is_asynchronous
;
}
libvlc_event_listener_t
;
typedef
struct
libvlc_event_manager_t
{
void
*
p_obj
;
struct
libvlc_instance_t
*
p_libvlc_instance
;
vlc_array_t
listeners_groups
;
vlc_mutex_t
object_lock
;
vlc_mutex_t
event_sending_lock
;
struct
libvlc_event_async_queue
*
async_event_queue
;
}
libvlc_event_sender_t
;
static
inline
bool
listeners_are_equal
(
libvlc_event_listener_t
*
listener1
,
libvlc_event_listener_t
*
listener2
)
{
return
listener1
->
event_type
==
listener2
->
event_type
&&
listener1
->
pf_callback
==
listener2
->
pf_callback
&&
listener1
->
p_user_data
==
listener2
->
p_user_data
&&
listener1
->
is_asynchronous
==
listener2
->
is_asynchronous
;
}
/* event_async.c */
void
libvlc_event_async_fini
(
libvlc_event_manager_t
*
p_em
);
void
libvlc_event_async_dispatch
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
,
libvlc_event_t
*
event
);
void
libvlc_event_async_ensure_listener_removal
(
libvlc_event_manager_t
*
p_em
,
libvlc_event_listener_t
*
listener
);
#endif
src/control/libvlc_internal.h
View file @
cba8b415
...
@@ -69,68 +69,6 @@ struct libvlc_instance_t
...
@@ -69,68 +69,6 @@ struct libvlc_instance_t
struct
libvlc_callback_entry_list_t
*
p_callback_list
;
struct
libvlc_callback_entry_list_t
*
p_callback_list
;
};
};
/*
* Event Handling
*/
/* Example usage
*
* struct libvlc_cool_object_t
* {
* ...
* libvlc_event_manager_t * p_event_manager;
* ...
* }
*
* libvlc_my_cool_object_new()
* {
* ...
* p_self->p_event_manager = libvlc_event_manager_new( p_self,
* p_self->p_libvlc_instance, p_e);
* libvlc_event_manager_register_event_type(p_self->p_event_manager,
* libvlc_MyCoolObjectDidSomething, p_e)
* ...
* }
*
* libvlc_my_cool_object_release()
* {
* ...
* libvlc_event_manager_release( p_self->p_event_manager );
* ...
* }
*
* libvlc_my_cool_object_do_something()
* {
* ...
* libvlc_event_t event;
* event.type = libvlc_MyCoolObjectDidSomething;
* event.u.my_cool_object_did_something.what_it_did = kSomething;
* libvlc_event_send( p_self->p_event_manager, &event );
* }
* */
typedef
struct
libvlc_event_listener_t
{
libvlc_event_type_t
event_type
;
void
*
p_user_data
;
libvlc_callback_t
pf_callback
;
}
libvlc_event_listener_t
;
typedef
struct
libvlc_event_listeners_group_t
{
libvlc_event_type_t
event_type
;
vlc_array_t
listeners
;
bool
b_sublistener_removed
;
}
libvlc_event_listeners_group_t
;
typedef
struct
libvlc_event_manager_t
{
void
*
p_obj
;
struct
libvlc_instance_t
*
p_libvlc_instance
;
vlc_array_t
listeners_groups
;
vlc_mutex_t
object_lock
;
vlc_mutex_t
event_sending_lock
;
}
libvlc_event_sender_t
;
/***************************************************************************
/***************************************************************************
* Other internal functions
* Other internal functions
...
@@ -153,6 +91,11 @@ void libvlc_event_send(
...
@@ -153,6 +91,11 @@ void libvlc_event_send(
libvlc_event_manager_t
*
p_em
,
libvlc_event_manager_t
*
p_em
,
libvlc_event_t
*
p_event
);
libvlc_event_t
*
p_event
);
void
libvlc_event_attach_async
(
libvlc_event_manager_t
*
p_event_manager
,
libvlc_event_type_t
event_type
,
libvlc_callback_t
pf_callback
,
void
*
p_user_data
,
libvlc_exception_t
*
p_e
);
/* Exception shorcuts */
/* Exception shorcuts */
...
...
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