[vlc-commits] variables: use linked listed for callbacks
Rémi Denis-Courmont
git at videolan.org
Tue Apr 17 21:35:11 CEST 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Apr 17 21:35:08 2018 +0300| [c3e4633e1687ec1f0e4a41b99e8eef8797d83abe] | committer: Rémi Denis-Courmont
variables: use linked listed for callbacks
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c3e4633e1687ec1f0e4a41b99e8eef8797d83abe
---
src/misc/variables.c | 144 ++++++++++++++++++++++++++-------------------------
1 file changed, 73 insertions(+), 71 deletions(-)
diff --git a/src/misc/variables.c b/src/misc/variables.c
index 2426215954..c1ebd64302 100644
--- a/src/misc/variables.c
+++ b/src/misc/variables.c
@@ -45,6 +45,7 @@
typedef struct callback_entry_t
{
+ struct callback_entry_t *next;
union
{
vlc_callback_t pf_value_callback;
@@ -61,12 +62,6 @@ typedef struct variable_ops_t
void (*pf_free) ( vlc_value_t * );
} variable_ops_t;
-typedef struct callback_table_t
-{
- int i_entries;
- callback_entry_t * p_entries;
-} callback_table_t;
-
/**
* The structure describing a variable.
* \note vlc_value_t is the common union for variable values
@@ -98,9 +93,9 @@ struct variable_t
bool b_incallback;
/** Registered value callbacks */
- callback_table_t value_callbacks;
+ callback_entry_t *value_callbacks;
/** Registered list callbacks */
- callback_table_t list_callbacks;
+ callback_entry_t *list_callbacks;
};
static int CmpBool( vlc_value_t v, vlc_value_t w )
@@ -176,7 +171,14 @@ static void Destroy( variable_t *p_var )
free( p_var->psz_name );
free( p_var->psz_text );
- free( p_var->value_callbacks.p_entries );
+ while (unlikely(p_var->value_callbacks != NULL))
+ {
+ callback_entry_t *next = p_var->value_callbacks->next;
+
+ free(p_var->value_callbacks);
+ p_var->value_callbacks = next;
+ }
+ assert(p_var->list_callbacks == NULL);
free( p_var );
}
@@ -237,20 +239,22 @@ static void TriggerCallback(vlc_object_t *obj, variable_t *var,
{
assert(obj != NULL);
- size_t count = var->value_callbacks.i_entries;
- if (count == 0)
+ callback_entry_t *entry = var->value_callbacks;
+ if (entry == NULL)
return;
- callback_entry_t *entries = var->value_callbacks.p_entries;
vlc_object_internals_t *priv = vlc_internals(obj);
assert(!var->b_incallback);
var->b_incallback = true;
vlc_mutex_unlock(&priv->var_lock);
- for (size_t i = 0; i < count; i++)
- entries[i].pf_value_callback(obj, name, prev, var->val,
- entries[i].p_data);
+ do
+ {
+ entry->pf_value_callback(obj, name, prev, var->val, entry->p_data);
+ entry = entry->next;
+ }
+ while (entry != NULL);
vlc_mutex_lock(&priv->var_lock);
var->b_incallback = false;
@@ -262,20 +266,22 @@ static void TriggerListCallback(vlc_object_t *obj, variable_t *var,
{
assert(obj != NULL);
- size_t count = var->list_callbacks.i_entries;
- if (count == 0)
+ callback_entry_t *entry = var->value_callbacks;
+ if (entry == NULL)
return;
- callback_entry_t *entries = var->list_callbacks.p_entries;
vlc_object_internals_t *priv = vlc_internals(obj);
assert(!var->b_incallback);
var->b_incallback = true;
vlc_mutex_unlock(&priv->var_lock);
- for (size_t i = 0; i < count; i++)
- entries[i].pf_list_callback(obj, name, action, val,
- entries[i].p_data);
+ do
+ {
+ entry->pf_list_callback(obj, name, action, val, entry->p_data);
+ entry = entry->next;
+ }
+ while (entry != NULL);
vlc_mutex_lock(&priv->var_lock);
var->b_incallback = false;
@@ -303,7 +309,7 @@ int (var_Create)( vlc_object_t *p_this, const char *psz_name, int i_type )
p_var->choices_text.p_values = NULL;
p_var->b_incallback = false;
- p_var->value_callbacks = (callback_table_t){ 0, NULL };
+ p_var->value_callbacks = NULL;
/* Always initialize the variable, even if it is a list variable; this
* will lead to errors if the variable is not initialized, but it will
@@ -759,7 +765,8 @@ typedef enum
} vlc_callback_type_t;
static void AddCallback( vlc_object_t *p_this, const char *psz_name,
- callback_entry_t entry, vlc_callback_type_t i_type )
+ callback_entry_t *restrict entry,
+ vlc_callback_type_t i_type )
{
variable_t *p_var;
@@ -772,18 +779,21 @@ static void AddCallback( vlc_object_t *p_this, const char *psz_name,
{
vlc_mutex_unlock( &p_priv->var_lock );
msg_Err( p_this, "cannot add callback %p to nonexistent variable '%s'",
- entry.p_callback, psz_name );
+ entry->p_callback, psz_name );
return;
}
WaitUnused( p_this, p_var );
- callback_table_t *p_table;
+ callback_entry_t **pp;
+
if (i_type == vlc_value_callback)
- p_table = &p_var->value_callbacks;
+ pp = &p_var->value_callbacks;
else
- p_table = &p_var->list_callbacks;
- TAB_APPEND(p_table->i_entries, p_table->p_entries, entry);
+ pp = &p_var->list_callbacks;
+
+ entry->next = *pp;
+ *pp = entry;
vlc_mutex_unlock( &p_priv->var_lock );
}
@@ -791,21 +801,19 @@ static void AddCallback( vlc_object_t *p_this, const char *psz_name,
void (var_AddCallback)(vlc_object_t *p_this, const char *psz_name,
vlc_callback_t pf_callback, void *p_data)
{
- callback_entry_t entry;
- entry.pf_value_callback = pf_callback;
- entry.p_data = p_data;
+ callback_entry_t *entry = xmalloc(sizeof (*entry));
+ entry->pf_value_callback = pf_callback;
+ entry->p_data = p_data;
AddCallback(p_this, psz_name, entry, vlc_value_callback);
}
static void DelCallback( vlc_object_t *p_this, const char *psz_name,
- callback_entry_t entry, vlc_callback_type_t i_type )
+ const callback_entry_t *restrict match,
+ vlc_callback_type_t i_type )
{
- int i_entry;
+ callback_entry_t **pp, *entry;
variable_t *p_var;
-#ifndef NDEBUG
- bool b_found_similar = false;
-#endif
assert( p_this );
@@ -816,46 +824,31 @@ static void DelCallback( vlc_object_t *p_this, const char *psz_name,
{
vlc_mutex_unlock( &p_priv->var_lock );
msg_Err( p_this, "cannot delete callback %p from nonexistent "
- "variable '%s'", entry.p_callback, psz_name );
+ "variable '%s'", match->p_callback, psz_name );
return;
}
WaitUnused( p_this, p_var );
- callback_table_t *p_table;
if (i_type == vlc_value_callback)
- p_table = &p_var->value_callbacks;
+ pp = &p_var->value_callbacks;
else
- p_table = &p_var->list_callbacks;
+ pp = &p_var->list_callbacks;
- for( i_entry = p_table->i_entries ; i_entry-- ; )
- {
- if( p_table->p_entries[i_entry].p_callback == entry.p_callback
- && p_table->p_entries[i_entry].p_data == entry.p_data )
- {
- break;
- }
-#ifndef NDEBUG
- else if( p_table->p_entries[i_entry].p_callback == entry.p_callback )
- b_found_similar = true;
-#endif
- }
+ entry = *pp;
+ assert(entry != NULL);
- if( i_entry < 0 )
+ while (entry->p_callback != match->p_callback
+ || entry->p_data != match->p_data)
{
-#ifndef NDEBUG
- if( b_found_similar )
- fprintf( stderr, "Calling var_DelCallback for '%s' with the same "
- "function but not the same data.", psz_name );
- vlc_assert_unreachable();
-#endif
- vlc_mutex_unlock( &p_priv->var_lock );
- return;
+ pp = &entry->next;
+ entry = *pp;
+ assert(entry != NULL);
}
- TAB_ERASE(p_table->i_entries, p_table->p_entries, i_entry);
-
+ *pp = entry->next;
vlc_mutex_unlock( &p_priv->var_lock );
+ free(entry);
}
void (var_DelCallback)(vlc_object_t *p_this, const char *psz_name,
@@ -865,7 +858,7 @@ void (var_DelCallback)(vlc_object_t *p_this, const char *psz_name,
entry.pf_value_callback = pf_callback;
entry.p_data = p_data;
- DelCallback(p_this, psz_name, entry, vlc_value_callback);
+ DelCallback(p_this, psz_name, &entry, vlc_value_callback);
}
void (var_TriggerCallback)(vlc_object_t *p_this, const char *psz_name)
@@ -886,10 +879,10 @@ void (var_TriggerCallback)(vlc_object_t *p_this, const char *psz_name)
void (var_AddListCallback)(vlc_object_t *p_this, const char *psz_name,
vlc_list_callback_t pf_callback, void *p_data)
{
- callback_entry_t entry;
- entry.pf_list_callback = pf_callback;
- entry.p_data = p_data;
+ callback_entry_t *entry = xmalloc(sizeof (*entry));
+ entry->pf_list_callback = pf_callback;
+ entry->p_data = p_data;
AddCallback(p_this, psz_name, entry, vlc_list_callback);
}
@@ -897,10 +890,10 @@ void (var_DelListCallback)(vlc_object_t *p_this, const char *psz_name,
vlc_list_callback_t pf_callback, void *p_data)
{
callback_entry_t entry;
+
entry.pf_list_callback = pf_callback;
entry.p_data = p_data;
-
- DelCallback(p_this, psz_name, entry, vlc_list_callback);
+ DelCallback(p_this, psz_name, &entry, vlc_list_callback);
}
/** Parse a stringified option
@@ -1187,8 +1180,17 @@ static void DumpVariable(const void *data, const VISIT which, const int depth)
fputs(", has choices", stdout);
if (var->i_type & VLC_VAR_ISCOMMAND)
fputs(", command", stdout);
- if (var->value_callbacks.i_entries)
- printf(", %d callbacks", var->value_callbacks.i_entries);
+ if (var->value_callbacks != NULL)
+ {
+ size_t count = 0;
+
+ for (callback_entry_t *entry = var->value_callbacks;
+ entry != NULL;
+ entry = entry->next)
+ count++;
+
+ printf(", %zu callbacks", count);
+ }
switch (var->i_type & VLC_VAR_CLASS)
{
More information about the vlc-commits
mailing list