mirror of
				https://github.com/Ryujinx/libsoundio.git
				synced 2025-11-04 06:34:55 +00:00 
			
		
		
		
	dummy: fix deadlock when pause called from write_callback
This commit is contained in:
		
							parent
							
								
									a3c4f85489
								
							
						
					
					
						commit
						277bb3106b
					
				| 
						 | 
				
			
			@ -44,6 +44,12 @@ static void playback_thread_run(void *arg) {
 | 
			
		|||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (osd->pause_requested.load()) {
 | 
			
		||||
            start_time = now;
 | 
			
		||||
            frames_consumed = 0;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int fill_bytes = soundio_ring_buffer_fill_count(&osd->ring_buffer);
 | 
			
		||||
        int fill_frames = fill_bytes / outstream->bytes_per_frame;
 | 
			
		||||
        int free_bytes = soundio_ring_buffer_capacity(&osd->ring_buffer) - fill_bytes;
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +92,12 @@ static void capture_thread_run(void *arg) {
 | 
			
		|||
        double relative_time = next_period - now;
 | 
			
		||||
        soundio_os_cond_timed_wait(isd->cond, nullptr, relative_time);
 | 
			
		||||
 | 
			
		||||
        if (isd->pause_requested.load()) {
 | 
			
		||||
            start_time = now;
 | 
			
		||||
            frames_consumed = 0;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int fill_bytes = soundio_ring_buffer_fill_count(&isd->ring_buffer);
 | 
			
		||||
        int free_bytes = soundio_ring_buffer_capacity(&isd->ring_buffer) - fill_bytes;
 | 
			
		||||
        int fill_frames = fill_bytes / instream->bytes_per_frame;
 | 
			
		||||
| 
						 | 
				
			
			@ -166,6 +178,7 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
 | 
			
		|||
    SoundIoDevice *device = outstream->device;
 | 
			
		||||
 | 
			
		||||
    osd->clear_buffer_flag.test_and_set();
 | 
			
		||||
    osd->pause_requested.store(false);
 | 
			
		||||
 | 
			
		||||
    if (outstream->software_latency == 0.0)
 | 
			
		||||
        outstream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max);
 | 
			
		||||
| 
						 | 
				
			
			@ -193,16 +206,14 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os)
 | 
			
		|||
 | 
			
		||||
static int outstream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) {
 | 
			
		||||
    SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
 | 
			
		||||
    SoundIo *soundio = &si->pub;
 | 
			
		||||
    if (pause) {
 | 
			
		||||
        if (osd->thread) {
 | 
			
		||||
            osd->abort_flag.clear();
 | 
			
		||||
            soundio_os_cond_signal(osd->cond, nullptr);
 | 
			
		||||
            soundio_os_thread_destroy(osd->thread);
 | 
			
		||||
            osd->thread = nullptr;
 | 
			
		||||
    osd->pause_requested.store(pause);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!osd->thread) {
 | 
			
		||||
 | 
			
		||||
static int outstream_start_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
 | 
			
		||||
    SoundIoOutStreamDummy *osd = &os->backend_data.dummy;
 | 
			
		||||
    SoundIo *soundio = &si->pub;
 | 
			
		||||
    assert(!osd->thread);
 | 
			
		||||
    osd->abort_flag.test_and_set();
 | 
			
		||||
    int err;
 | 
			
		||||
    if ((err = soundio_os_thread_create(playback_thread_run, os,
 | 
			
		||||
| 
						 | 
				
			
			@ -210,15 +221,9 @@ static int outstream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoOutStr
 | 
			
		|||
    {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int outstream_start_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
 | 
			
		||||
    return outstream_pause_dummy(si, os, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int outstream_begin_write_dummy(SoundIoPrivate *si,
 | 
			
		||||
        SoundIoOutStreamPrivate *os, SoundIoChannelArea **out_areas, int *frame_count)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -284,6 +289,7 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
 | 
			
		|||
    SoundIoInStream *instream = &is->pub;
 | 
			
		||||
    SoundIoDevice *device = instream->device;
 | 
			
		||||
 | 
			
		||||
    isd->pause_requested.store(false);
 | 
			
		||||
 | 
			
		||||
    if (instream->software_latency == 0.0)
 | 
			
		||||
        instream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max);
 | 
			
		||||
| 
						 | 
				
			
			@ -313,16 +319,14 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
 | 
			
		|||
 | 
			
		||||
static int instream_pause_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) {
 | 
			
		||||
    SoundIoInStreamDummy *isd = &is->backend_data.dummy;
 | 
			
		||||
    SoundIo *soundio = &si->pub;
 | 
			
		||||
    if (pause) {
 | 
			
		||||
        if (isd->thread) {
 | 
			
		||||
            isd->abort_flag.clear();
 | 
			
		||||
            soundio_os_cond_signal(isd->cond, nullptr);
 | 
			
		||||
            soundio_os_thread_destroy(isd->thread);
 | 
			
		||||
            isd->thread = nullptr;
 | 
			
		||||
    isd->pause_requested.store(pause);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!isd->thread) {
 | 
			
		||||
 | 
			
		||||
static int instream_start_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
 | 
			
		||||
    SoundIoInStreamDummy *isd = &is->backend_data.dummy;
 | 
			
		||||
    SoundIo *soundio = &si->pub;
 | 
			
		||||
    assert(!isd->thread);
 | 
			
		||||
    isd->abort_flag.test_and_set();
 | 
			
		||||
    int err;
 | 
			
		||||
    if ((err = soundio_os_thread_create(capture_thread_run, is,
 | 
			
		||||
| 
						 | 
				
			
			@ -330,15 +334,9 @@ static int instream_pause_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is,
 | 
			
		|||
    {
 | 
			
		||||
        return err;
 | 
			
		||||
    }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int instream_start_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
 | 
			
		||||
    return instream_pause_dummy(si, is, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int instream_begin_read_dummy(SoundIoPrivate *si,
 | 
			
		||||
        SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ struct SoundIoOutStreamDummy {
 | 
			
		|||
    struct SoundIoRingBuffer ring_buffer;
 | 
			
		||||
    double playback_start_time;
 | 
			
		||||
    atomic_flag clear_buffer_flag;
 | 
			
		||||
    atomic_bool pause_requested;
 | 
			
		||||
    SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,7 @@ struct SoundIoInStreamDummy {
 | 
			
		|||
    int read_frame_count;
 | 
			
		||||
    int buffer_frame_count;
 | 
			
		||||
    struct SoundIoRingBuffer ring_buffer;
 | 
			
		||||
    atomic_bool pause_requested;
 | 
			
		||||
    SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue