Example #1
0
/**
 * Destroy a vlc variable
 *
 * Look for the variable and destroy it if it is found. As in var_Create we
 * do a call to memmove() but we have performance counterparts elsewhere.
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 */
void (var_Destroy)(vlc_object_t *p_this, const char *psz_name)
{
    variable_t *p_var;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return;
    }

    WaitUnused( p_this, p_var );

    if( --p_var->i_usage == 0 )
        tdelete( p_var, &p_priv->var_root, varcmp );
    else
        p_var = NULL;
    vlc_mutex_unlock( &p_priv->var_lock );

    if( p_var != NULL )
        Destroy( p_var );
}
Example #2
0
static void AddCallback( vlc_object_t *p_this, const char *psz_name,
                        callback_entry_t entry, vlc_callback_type_t i_type )
{
    variable_t *p_var;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        msg_Err( p_this, "cannot add callback %p to nonexistent variable '%s'",
                 entry.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;
    else
        p_table = &p_var->list_callbacks;
    TAB_APPEND(p_table->i_entries, p_table->p_entries, entry);

    vlc_mutex_unlock( &p_priv->var_lock );
}
Example #3
0
/**
 * Perform a Get and Set on a variable
 *
 * \param p_this: The object that hold the variable
 * \param psz_name: the name of the variable
 * \param i_action: the action to perform
 * \param p_val: The action parameter
 * \return vlc error codes
 */
int var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action,
                   vlc_value_t *p_val )
{
    variable_t *p_var;
    vlc_value_t oldval;

    assert( p_this );
    assert( p_val );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );

    /* Duplicated data if needed */
    //p_var->ops->pf_dup( &val );

    /* Backup needed stuff */
    oldval = p_var->val;

    /* depending of the action requiered */
    switch( i_action )
    {
    case VLC_VAR_BOOL_TOGGLE:
        assert( ( p_var->i_type & VLC_VAR_BOOL ) == VLC_VAR_BOOL );
        p_var->val.b_bool = !p_var->val.b_bool;
        break;
    case VLC_VAR_INTEGER_ADD:
        assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER );
        p_var->val.i_int += p_val->i_int;
        break;
    case VLC_VAR_INTEGER_OR:
        assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER );
        p_var->val.i_int |= p_val->i_int;
        break;
    case VLC_VAR_INTEGER_NAND:
        assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER );
        p_var->val.i_int &= ~p_val->i_int;
        break;
    default:
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_EGENERIC;
    }

    /*  Check boundaries */
    CheckValue( p_var, &p_var->val );
    *p_val = p_var->val;

    /* Deal with callbacks.*/
    TriggerCallback( p_this, p_var, psz_name, oldval );

    vlc_mutex_unlock( &p_priv->var_lock );
    return VLC_SUCCESS;
}
Example #4
0
/**
 * Trigger callback on a variable
 *
 * \param p_this The object that hold the variable
 * \param psz_name The name of the variable
 */
int var_TriggerCallback( vlc_object_t *p_this, const char *psz_name )
{
    int i_ret;
    variable_t *p_var;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );

    /* Deal with callbacks. Tell we're in a callback, release the lock,
     * call stored functions, retake the lock. */
    i_ret = TriggerCallback( p_this, p_var, psz_name, p_var->val );

    vlc_mutex_unlock( &p_priv->var_lock );
    return i_ret;
}
Example #5
0
/**
 * Register a callback in a variable
 *
 * We store a function pointer that will be called upon variable
 * modification.
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 * \param pf_callback The function pointer
 * \param p_data A generic pointer that will be passed as the last
 *               argument to the callback function.
 *
 * \warning The callback function is run in the thread that calls var_Set on
 *          the variable. Use proper locking. This thread may not have much
 *          time to spare, so keep callback functions short.
 */
int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
                     vlc_callback_t pf_callback, void *p_data )
{
    variable_t *p_var;
    callback_entry_t entry;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    entry.pf_callback = pf_callback;
    entry.p_data = p_data;

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        msg_Err( p_this, "cannot add callback %p to nonexistent "
                 "variable '%s'", pf_callback, psz_name );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );
    INSERT_ELEM( p_var->p_entries,
                 p_var->i_entries,
                 p_var->i_entries,
                 entry );

    vlc_mutex_unlock( &p_priv->var_lock );

    return VLC_SUCCESS;
}
Example #6
0
static void DelCallback( vlc_object_t *p_this, const char *psz_name,
                         callback_entry_t entry, vlc_callback_type_t i_type )
{
    int i_entry;
    variable_t *p_var;
#ifndef NDEBUG
    bool b_found_similar = false;
#endif

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        msg_Err( p_this, "cannot delete callback %p from nonexistent "
                 "variable '%s'", entry.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;
    else
        p_table = &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
    }

    if( i_entry < 0 )
    {
#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;
    }

    TAB_ERASE(p_table->i_entries, p_table->p_entries, i_entry);

    vlc_mutex_unlock( &p_priv->var_lock );
}
Example #7
0
/**
 * Remove a callback from a variable
 *
 * pf_callback and p_data have to be given again, because different objects
 * might have registered the same callback function.
 */
int var_DelCallback( vlc_object_t *p_this, const char *psz_name,
                     vlc_callback_t pf_callback, void *p_data )
{
    int i_entry;
    variable_t *p_var;
#ifndef NDEBUG
    bool b_found_similar = false;
#endif

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );

    for( i_entry = p_var->i_entries ; i_entry-- ; )
    {
        if( p_var->p_entries[i_entry].pf_callback == pf_callback
            && p_var->p_entries[i_entry].p_data == p_data )
        {
            break;
        }
#ifndef NDEBUG
        else if( p_var->p_entries[i_entry].pf_callback == pf_callback )
            b_found_similar = true;
#endif
    }

    if( i_entry < 0 )
    {
#ifndef NDEBUG
        if( b_found_similar )
            fprintf( stderr, "Calling var_DelCallback for '%s' with the same "
                             "function but not the same data.", psz_name );
        assert( 0 );
#endif
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_EGENERIC;
    }

    REMOVE_ELEM( p_var->p_entries, p_var->i_entries, i_entry );

    vlc_mutex_unlock( &p_priv->var_lock );

    return VLC_SUCCESS;
}
Example #8
0
int var_SetChecked( vlc_object_t *p_this, const char *psz_name,
                    int expected_type, vlc_value_t val )
{
    int i_ret = VLC_SUCCESS;
    variable_t *p_var;
    vlc_value_t oldval;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    assert( expected_type == 0 ||
            (p_var->i_type & VLC_VAR_CLASS) == expected_type );
#ifndef NDEBUG
        /* Alert if the type is VLC_VAR_VOID */
        if( ( p_var->i_type & VLC_VAR_TYPE ) == VLC_VAR_VOID )
            msg_Warn( p_this, "Calling var_Set on the void variable '%s' (0x%04x)", psz_name, p_var->i_type );
#endif


    WaitUnused( p_this, p_var );

    /* Duplicate data if needed */
    p_var->ops->pf_dup( &val );

    /* Backup needed stuff */
    oldval = p_var->val;

    /* Check boundaries and list */
    CheckValue( p_var, &val );

    /* Set the variable */
    p_var->val = val;

    /* Deal with callbacks */
    i_ret = TriggerCallback( p_this, p_var, psz_name, oldval );

    /* Free data if needed */
    p_var->ops->pf_free( &oldval );

    vlc_mutex_unlock( &p_priv->var_lock );

    return i_ret;
}
Example #9
0
/**
 * Trigger callback on a variable
 *
 * \param p_this The object that hold the variable
 * \param psz_name The name of the variable
 */
void var_TriggerCallback( vlc_object_t *p_this, const char *psz_name )
{
    vlc_object_internals_t *p_priv = vlc_internals( p_this );
    variable_t *p_var = Lookup( p_this, psz_name );
    if( p_var != NULL )
    {
        WaitUnused( p_this, p_var );

        /* Deal with callbacks. Tell we're in a callback, release the lock,
         * call stored functions, retake the lock. */
        TriggerCallback( p_this, p_var, psz_name, p_var->val );
    }
    vlc_mutex_unlock( &p_priv->var_lock );
}
Example #10
0
int var_SetChecked( vlc_object_t *p_this, const char *psz_name,
                    int expected_type, vlc_value_t val )
{
    variable_t *p_var;
    vlc_value_t oldval;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    assert( expected_type == 0 ||
            (p_var->i_type & VLC_VAR_CLASS) == expected_type );
    assert ((p_var->i_type & VLC_VAR_CLASS) != VLC_VAR_VOID);

    WaitUnused( p_this, p_var );

    /* Duplicate data if needed */
    p_var->ops->pf_dup( &val );

    /* Backup needed stuff */
    oldval = p_var->val;

    /* Check boundaries and list */
    CheckValue( p_var, &val );

    /* Set the variable */
    p_var->val = val;

    /* Deal with callbacks */
    TriggerCallback( p_this, p_var, psz_name, oldval );

    /* Free data if needed */
    p_var->ops->pf_free( &oldval );

    vlc_mutex_unlock( &p_priv->var_lock );
    return VLC_SUCCESS;
}
Example #11
0
/**
 * Register a callback in a variable
 *
 * We store a function pointer that will be called upon variable
 * modification.
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 * \param pf_callback The function pointer
 * \param p_data A generic pointer that will be passed as the last
 *               argument to the callback function.
 *
 * \warning The callback function is run in the thread that calls var_Set on
 *          the variable. Use proper locking. This thread may not have much
 *          time to spare, so keep callback functions short.
 */
int var_AddCallback( vlc_object_t *p_this, const char *psz_name,
                     vlc_callback_t pf_callback, void *p_data )
{
    variable_t *p_var;
    callback_entry_t entry;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    entry.pf_callback = pf_callback;
    entry.p_data = p_data;

    vlc_mutex_lock( &p_priv->var_lock );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
#ifndef NDEBUG
        msg_Warn( p_this, "Failed to add a callback to the non-existing "
                          "variable '%s'", psz_name );
#endif
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    WaitUnused( p_this, p_var );
    INSERT_ELEM( p_var->p_entries,
                 p_var->i_entries,
                 p_var->i_entries,
                 entry );

    vlc_mutex_unlock( &p_priv->var_lock );

    return VLC_SUCCESS;
}