mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	pcm_plugin: fix appl pointer not correct when mmap_commit() return error
When snd_pcm_mmap_commit() return error, the appl pointer is also updated. which cause the avail_update()'s result wrong. This patch move the snd_pcm_mmap_appl_forward() to the place when snd_pcm_mmap_commit() is successfully returned. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
		
							parent
							
								
									6a610e56ae
								
							
						
					
					
						commit
						7c424edd11
					
				
					 1 changed files with 32 additions and 16 deletions
				
			
		| 
						 | 
					@ -279,18 +279,22 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
 | 
				
			||||||
			return -EPIPE;
 | 
								return -EPIPE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		snd_atomic_write_begin(&plugin->watom);
 | 
							snd_atomic_write_begin(&plugin->watom);
 | 
				
			||||||
		snd_pcm_mmap_appl_forward(pcm, frames);
 | 
					 | 
				
			||||||
		result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
							result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
				
			||||||
		if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
							if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
				
			||||||
			snd_pcm_sframes_t res;
 | 
								snd_pcm_sframes_t res;
 | 
				
			||||||
			res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
 | 
								res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
 | 
				
			||||||
			if (res < 0)
 | 
								if (res < 0) {
 | 
				
			||||||
 | 
									snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
				return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
									return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			frames -= res;
 | 
								frames -= res;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (result <= 0) {
 | 
				
			||||||
			snd_atomic_write_end(&plugin->watom);
 | 
								snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
		if (result <= 0)
 | 
					 | 
				
			||||||
			return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
								return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							snd_pcm_mmap_appl_forward(pcm, frames);
 | 
				
			||||||
 | 
							snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
		offset += frames;
 | 
							offset += frames;
 | 
				
			||||||
		xfer += frames;
 | 
							xfer += frames;
 | 
				
			||||||
		size -= frames;
 | 
							size -= frames;
 | 
				
			||||||
| 
						 | 
					@ -325,19 +329,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
 | 
				
			||||||
			return -EPIPE;
 | 
								return -EPIPE;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		snd_atomic_write_begin(&plugin->watom);
 | 
							snd_atomic_write_begin(&plugin->watom);
 | 
				
			||||||
		snd_pcm_mmap_appl_forward(pcm, frames);
 | 
					 | 
				
			||||||
		result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
							result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
				
			||||||
		if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
							if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
				
			||||||
			snd_pcm_sframes_t res;
 | 
								snd_pcm_sframes_t res;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			res = plugin->undo_read(slave, areas, offset, frames, slave_frames - result);
 | 
								res = plugin->undo_read(slave, areas, offset, frames, slave_frames - result);
 | 
				
			||||||
			if (res < 0)
 | 
								if (res < 0) {
 | 
				
			||||||
 | 
									snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
				return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
									return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			frames -= res;
 | 
								frames -= res;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (result <= 0) {
 | 
				
			||||||
			snd_atomic_write_end(&plugin->watom);
 | 
								snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
		if (result <= 0)
 | 
					 | 
				
			||||||
			return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
								return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							snd_pcm_mmap_appl_forward(pcm, frames);
 | 
				
			||||||
 | 
							snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
		offset += frames;
 | 
							offset += frames;
 | 
				
			||||||
		xfer += frames;
 | 
							xfer += frames;
 | 
				
			||||||
		size -= frames;
 | 
							size -= frames;
 | 
				
			||||||
| 
						 | 
					@ -423,19 +431,23 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
 | 
				
			||||||
		frames = plugin->write(pcm, areas, appl_offset, frames,
 | 
							frames = plugin->write(pcm, areas, appl_offset, frames,
 | 
				
			||||||
				       slave_areas, slave_offset, &slave_frames);
 | 
									       slave_areas, slave_offset, &slave_frames);
 | 
				
			||||||
		snd_atomic_write_begin(&plugin->watom);
 | 
							snd_atomic_write_begin(&plugin->watom);
 | 
				
			||||||
		snd_pcm_mmap_appl_forward(pcm, frames);
 | 
					 | 
				
			||||||
		result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
							result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
				
			||||||
		snd_atomic_write_end(&plugin->watom);
 | 
					 | 
				
			||||||
		if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
							if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
				
			||||||
			snd_pcm_sframes_t res;
 | 
								snd_pcm_sframes_t res;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
 | 
								res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
 | 
				
			||||||
			if (res < 0)
 | 
								if (res < 0) {
 | 
				
			||||||
 | 
									snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
				return xfer > 0 ? xfer : res;
 | 
									return xfer > 0 ? xfer : res;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			frames -= res;
 | 
								frames -= res;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (result <= 0)
 | 
							if (result <= 0) {
 | 
				
			||||||
 | 
								snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
			return xfer > 0 ? xfer : result;
 | 
								return xfer > 0 ? xfer : result;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							snd_pcm_mmap_appl_forward(pcm, frames);
 | 
				
			||||||
 | 
							snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
		if (frames == cont)
 | 
							if (frames == cont)
 | 
				
			||||||
			appl_offset = 0;
 | 
								appl_offset = 0;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
| 
						 | 
					@ -490,19 +502,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
 | 
				
			||||||
			frames = (plugin->read)(pcm, areas, hw_offset, frames,
 | 
								frames = (plugin->read)(pcm, areas, hw_offset, frames,
 | 
				
			||||||
					      slave_areas, slave_offset, &slave_frames);
 | 
										      slave_areas, slave_offset, &slave_frames);
 | 
				
			||||||
			snd_atomic_write_begin(&plugin->watom);
 | 
								snd_atomic_write_begin(&plugin->watom);
 | 
				
			||||||
			snd_pcm_mmap_hw_forward(pcm, frames);
 | 
					 | 
				
			||||||
			result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
								result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
 | 
				
			||||||
			snd_atomic_write_end(&plugin->watom);
 | 
					 | 
				
			||||||
			if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
								if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
 | 
				
			||||||
				snd_pcm_sframes_t res;
 | 
									snd_pcm_sframes_t res;
 | 
				
			||||||
				
 | 
									
 | 
				
			||||||
				res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
 | 
									res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
 | 
				
			||||||
				if (res < 0)
 | 
									if (res < 0) {
 | 
				
			||||||
 | 
										snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
					return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
										return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				frames -= res;
 | 
									frames -= res;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (result <= 0)
 | 
								if (result <= 0) {
 | 
				
			||||||
 | 
									snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
				return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
									return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								snd_pcm_mmap_hw_forward(pcm, frames);
 | 
				
			||||||
 | 
								snd_atomic_write_end(&plugin->watom);
 | 
				
			||||||
			if (frames == cont)
 | 
								if (frames == cont)
 | 
				
			||||||
				hw_offset = 0;
 | 
									hw_offset = 0;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue