mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Fix mmap with multi plugin
The mmap of multi plugin seems broken (for a long time!) due to its creation of local buffer via snd_pcm_mmap(). Since the multi plugin just needs to shadow the mmap buffer of each slave, it now has mmap_shadow=1 and its own mmap/unmap method to do shadowing.
This commit is contained in:
		
							parent
							
								
									683c8bc4a2
								
							
						
					
					
						commit
						0b66de95a9
					
				
					 1 changed files with 34 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -690,13 +690,44 @@ static snd_pcm_sframes_t snd_pcm_multi_mmap_commit(snd_pcm_t *pcm,
 | 
			
		|||
	return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int snd_pcm_multi_mmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 | 
			
		||||
static int snd_pcm_multi_munmap(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	free(pcm->mmap_channels);
 | 
			
		||||
	free(pcm->running_areas);
 | 
			
		||||
	pcm->mmap_channels = NULL;
 | 
			
		||||
	pcm->running_areas = NULL;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int snd_pcm_multi_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
 | 
			
		||||
static int snd_pcm_multi_mmap(snd_pcm_t *pcm)
 | 
			
		||||
{
 | 
			
		||||
	snd_pcm_multi_t *multi = pcm->private_data;
 | 
			
		||||
	unsigned int c;
 | 
			
		||||
 | 
			
		||||
	pcm->mmap_channels = calloc(pcm->channels,
 | 
			
		||||
				    sizeof(pcm->mmap_channels[0]));
 | 
			
		||||
	pcm->running_areas = calloc(pcm->channels,
 | 
			
		||||
				    sizeof(pcm->running_areas[0]));
 | 
			
		||||
	if (!pcm->mmap_channels || !pcm->running_areas) {
 | 
			
		||||
		snd_pcm_multi_munmap(pcm);
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Copy the slave mmapped buffer data */
 | 
			
		||||
	for (c = 0; c < pcm->channels; c++) {
 | 
			
		||||
		snd_pcm_multi_channel_t *chan = &multi->channels[c];
 | 
			
		||||
		snd_pcm_t *slave;
 | 
			
		||||
		if (chan->slave_idx < 0) {
 | 
			
		||||
			snd_pcm_multi_munmap(pcm);
 | 
			
		||||
			return -ENXIO;
 | 
			
		||||
		}
 | 
			
		||||
		slave = multi->slaves[chan->slave_idx].pcm;
 | 
			
		||||
		pcm->mmap_channels[c] =
 | 
			
		||||
			slave->mmap_channels[chan->slave_channel];
 | 
			
		||||
		pcm->mmap_channels[c].channel = c;
 | 
			
		||||
		pcm->running_areas[c] =
 | 
			
		||||
			slave->running_areas[chan->slave_channel];
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -850,6 +881,7 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
 | 
			
		|||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
	pcm->mmap_rw = 1;
 | 
			
		||||
	pcm->mmap_shadow = 1; /* has own mmap method */
 | 
			
		||||
	pcm->ops = &snd_pcm_multi_ops;
 | 
			
		||||
	pcm->fast_ops = &snd_pcm_multi_fast_ops;
 | 
			
		||||
	pcm->private_data = multi;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue