brson / rust-sdl

SDL bindings for Rust
MIT License
179 stars 52 forks source link

Rust runtime error when using audio callback and Arc<RWLock>> #134

Closed mvdnes closed 10 years ago

mvdnes commented 10 years ago

Description

Currently I am trying to implement a audio in a multi-threaded rust program. One task will write data to an DList, and SDL should read from that and take the information (if available).

To accomplish this, I am using an Arc<RWLock<DList<u8>>>>, staticly created using the lazy_static library. However, when the audio callback is called, the program produces a runtime error.

One thing to note is that this also occurs when using a closure (which can run without using lazy_static). I found out about this by transforming the type pub type AudioCallback<'a> = |&mut [u8]|:'a;.

I am very unsure wether this is a Rust bug, or an rust-sdl one, so I thought on posting it here first.

Version

[mvdnes@vm-arch temp]$ rustc -v
rustc 0.11.0 (c97f885aee24dc28b82aa9d7a7d118d59c02ecbf 2014-07-06 20:36:35 +0000)

[mvdnes@vm-arch temp]$ uname -a
Linux vm-arch 3.15.3-1-ARCH #1 SMP PREEMPT Tue Jul 1 07:32:45 CEST 2014 x86_64 GNU/Linux

Trace

(gdb) break abort
Breakpoint 1 at 0x402960
(gdb) run
Starting program: /home/mvdnes/playground/temp/temp_fn 
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
[New Thread 0x7ffff3501700 (LWP 14596)]

There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.[New Thread 0x7ffff2d00700 (LWP 14597)]

fatal runtime error:  assertion failed: !ptr.is_null()

Program received signal SIGILL, Illegal instruction.
[Switching to Thread 0x7ffff3501700 (LWP 14596)]
0x0000000000489389 in util::abort::h32d839b9b615b3ceFGa ()
(gdb) bt
#0  0x0000000000489389 in util::abort::h32d839b9b615b3ceFGa ()
#1  0x00000000004852bd in local_ptr::compiled::take::h440988594255534974 ()
#2  0x00000000004889c7 in lock::failing::h3c5abfc3d27477b87Gf ()
#3  0x0000000000488b9f in lock::PoisonOnFail$LT$$x27a$GT$::new::hdfa0c6885184b6a9NIf ()
#4  0x0000000000417925 in lock::RWLock$LT$T$GT$::write::h13551060966698419214 ()
#5  0x0000000000417411 in temp_fn::cb (v=...) at temp_fn.rs:17
#6  0x0000000000418b29 in cb::as_closure.2888 ()
#7  0x000000000045f920 in audio::native_callback::__rust_abi ()
#8  0x000000000045f7ea in audio::native_callback::hbf6648ec3943ccabVha ()
#9  0x00007ffff7b4c8b9 in ?? () from /usr/lib/libSDL-1.2.so.0
#10 0x00007ffff7b54b78 in ?? () from /usr/lib/libSDL-1.2.so.0
#11 0x00007ffff7b954f9 in ?? () from /usr/lib/libSDL-1.2.so.0
#12 0x00007ffff7729124 in start_thread () from /usr/lib/libpthread.so.0
#13 0x00007ffff72474bd in clone () from /usr/lib/libc.so.6
(gdb) 

Example code

#![feature(phase)]

#[phase(plugin, link)] extern crate log;
#[phase(plugin)] extern crate lazy_static;
extern crate sdl;

use std::sync::{Arc, RWLock};

lazy_static! {
    static ref FOO: Arc<RWLock<uint>> = Arc::new(RWLock::new(0));
}

fn cb(v: &mut [u8])
{
    let foo = FOO.clone();
    let mut data = foo.write();
    *data = 2;
    for i in range(0, v.len()) { v[i] = 0; }
}

fn main()
{
    let spec = sdl::audio::DesiredAudioSpec
    {   
        freq: 44100,
        format: sdl::audio::S8AudioFormat,
        channels: sdl::audio::Stereo,
        samples: 4096,
        callback: cb, 
    };  
    match sdl::audio::open(spec)
    {   
        Ok(_) => {}, 
        Err(()) => error!("Could not open audio"),
    }   
    sdl::audio::pause(false);
    std::io::timer::sleep(1000);
    sdl::audio::close();
}
mvdnes commented 10 years ago

I found out on the IRC that RWLocks cannot be used outside of runtime.