Hello community, here is the log from the commit of package alsa checked in at Fri Apr 28 21:08:40 CEST 2006. -------- --- alsa/alsa.changes 2006-04-24 18:28:17.000000000 +0200 +++ STABLE/alsa/alsa.changes 2006-04-27 15:56:23.000000000 +0200 @@ -1,0 +2,7 @@ +Thu Apr 27 12:59:36 CEST 2006 - tiwai@suse.de + +- fix segfault with direct plugins when invalid channel binding + parameters are given. +- fix CPU hog by artsd together with rate plugin. + +------------------------------------------------------------------- New: ---- alsa-lib-dmix-binding-range-check.diff alsa-lib-fix-rate-cpu-hog-in-start.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ alsa.spec ++++++ --- /var/tmp/diff_new_pack.KdJjig/_old 2006-04-28 21:07:33.000000000 +0200 +++ /var/tmp/diff_new_pack.KdJjig/_new 2006-04-28 21:07:33.000000000 +0200 @@ -21,7 +21,7 @@ Autoreqprov: on Summary: Advanced Linux Sound Architecture Version: 1.0.11 -Release: 27 +Release: 30 Source1: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2 Source2: ftp://ftp.alsa-project.org/pub/util/alsa-utils-%{package_version}.tar.bz2 # Source5: ftp://ftp.alsa-project.org/pub/oss/alsa-oss-%{package_version}.tar.bz2 @@ -72,6 +72,8 @@ Patch34: alsa-lib-32bit-compat-fix.diff Patch35: alsa-lib-applptr-sync-fix.diff Patch36: alsa-lib-dmix-max-periods.diff +Patch37: alsa-lib-dmix-binding-range-check.diff +Patch38: alsa-lib-fix-rate-cpu-hog-in-start.diff Patch50: alsa-utils-speaker-test-5.1-fix.diff Patch51: alsa-utils-speaker-test-buffer-fix.diff Patch52: alsa-utils-alsaconf-lspci-fix.diff @@ -157,6 +159,8 @@ %patch34 -p1 %patch35 -p1 %patch36 -p1 +%patch37 -p1 +%patch38 -p1 cd .. cd alsa-utils*/. # %patch2 -p1 @@ -440,6 +444,10 @@ %doc alsa-lib*/doc/doxygen/html/* %changelog -n alsa +* Thu Apr 27 2006 - tiwai@suse.de +- fix segfault with direct plugins when invalid channel binding + parameters are given. +- fix CPU hog by artsd together with rate plugin. * Mon Apr 24 2006 - tiwai@suse.de - fix udev rules to use "==" instead of "=". * Wed Apr 12 2006 - tiwai@suse.de ++++++ alsa-lib-dmix-binding-range-check.diff ++++++ diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c --- a/src/pcm/pcm_direct.c Tue Apr 25 15:32:48 2006 +++ b/src/pcm/pcm_direct.c Wed Apr 26 16:30:44 2006 @@ -1223,10 +1223,13 @@ * id == client channel * value == slave's channel */ -int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, snd_config_t *cfg) +int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, + struct slave_params *params, + snd_config_t *cfg) { snd_config_iterator_t i, next; unsigned int chn, chn1, count = 0; + unsigned int *bindings; int err; dmix->channels = UINT_MAX; @@ -1256,11 +1259,11 @@ SNDERR("client channel out of range"); return -EINVAL; } - dmix->bindings = malloc(count * sizeof(unsigned int)); - if (dmix->bindings == NULL) + bindings = malloc(count * sizeof(unsigned int)); + if (bindings == NULL) return -ENOMEM; for (chn = 0; chn < count; chn++) - dmix->bindings[chn] = UINT_MAX; /* don't route */ + bindings[chn] = UINT_MAX; /* don't route */ snd_config_for_each(i, next, cfg) { snd_config_t *n = snd_config_iterator_entry(i); const char *id; @@ -1270,9 +1273,16 @@ safe_strtol(id, &cchannel); if (snd_config_get_integer(n, &schannel) < 0) { SNDERR("unable to get slave channel (should be integer type) in binding: %s\n", id); + free(bindings); return -EINVAL; } - dmix->bindings[cchannel] = schannel; + if (schannel < 0 || schannel >= params->channels) { + SNDERR("invalid slave channel number %d in binding to %d", + schannel, cchannel); + free(bindings); + return -EINVAL; + } + bindings[cchannel] = schannel; } if (dmix->type == SND_PCM_TYPE_DSNOOP) goto __skip_same_dst; @@ -1280,13 +1290,15 @@ for (chn1 = 0; chn1 < count; chn1++) { if (chn == chn1) continue; - if (dmix->bindings[chn] == dmix->bindings[chn1]) { - SNDERR("unable to route channels %d,%d to same destination %d", chn, chn1, dmix->bindings[chn]); + if (bindings[chn] == dmix->bindings[chn1]) { + SNDERR("unable to route channels %d,%d to same destination %d", chn, chn1, bindings[chn]); + free(bindings); return -EINVAL; } } } __skip_same_dst: + dmix->bindings = bindings; dmix->channels = count; return 0; } diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h --- a/src/pcm/pcm_direct.h Tue Apr 25 15:32:48 2006 +++ b/src/pcm/pcm_direct.h Wed Apr 26 16:30:44 2006 @@ -170,7 +170,9 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, struct slave_params *params); int snd_pcm_direct_initialize_poll_fd(snd_pcm_direct_t *dmix); int snd_pcm_direct_check_interleave(snd_pcm_direct_t *dmix, snd_pcm_t *pcm); -int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, snd_config_t *cfg); +int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix, + struct slave_params *params, + snd_config_t *cfg); int snd_pcm_direct_nonblock(snd_pcm_t *pcm, int nonblock); int snd_pcm_direct_async(snd_pcm_t *pcm, int sig, pid_t pid); int snd_pcm_direct_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c --- a/src/pcm/pcm_dmix.c Tue Apr 25 15:32:48 2006 +++ b/src/pcm/pcm_dmix.c Wed Apr 26 16:30:44 2006 @@ -808,7 +808,7 @@ goto _err_nosem; } - ret = snd_pcm_direct_parse_bindings(dmix, opts->bindings); + ret = snd_pcm_direct_parse_bindings(dmix, params, opts->bindings); if (ret < 0) goto _err_nosem; diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c --- a/src/pcm/pcm_dshare.c Tue Apr 25 15:32:48 2006 +++ b/src/pcm/pcm_dshare.c Wed Apr 26 16:30:44 2006 @@ -614,7 +614,7 @@ goto _err_nosem; } - ret = snd_pcm_direct_parse_bindings(dshare, opts->bindings); + ret = snd_pcm_direct_parse_bindings(dshare, params, opts->bindings); if (ret < 0) goto _err_nosem; @@ -706,7 +706,6 @@ snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT); ret = snd_pcm_direct_open_secondary_client(&spcm, dshare, "dshare_client"); - ret = snd_pcm_hw_open_fd(&spcm, "dshare_client", dshare->hw_fd, 0, 0); if (ret < 0) goto _err; dshare->spcm = spcm; diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c --- a/src/pcm/pcm_dsnoop.c Tue Apr 25 15:32:48 2006 +++ b/src/pcm/pcm_dsnoop.c Wed Apr 26 16:30:44 2006 @@ -502,7 +502,7 @@ goto _err_nosem; } - ret = snd_pcm_direct_parse_bindings(dsnoop, opts->bindings); + ret = snd_pcm_direct_parse_bindings(dsnoop, params, opts->bindings); if (ret < 0) goto _err_nosem; ++++++ alsa-lib-fix-rate-cpu-hog-in-start.diff ++++++ --- alsa-lib-1.0.11rc2/src/pcm/pcm_rate.c-dist 2006-04-27 16:00:51.000000000 +0200 +++ alsa-lib-1.0.11rc2/src/pcm/pcm_rate.c 2006-04-27 16:02:07.000000000 +0200 @@ -85,6 +85,8 @@ struct _snd_pcm_rate { snd_pcm_channel_area_t *pareas; /* areas for splitted period (rate pcm) */ snd_pcm_channel_area_t *sareas; /* areas for splitted period (slave pcm) */ int16_t *old_sample; + int start_pending; + snd_htimestamp_t trigger_tstamp; }; static void snd_pcm_rate_expand(const snd_pcm_channel_area_t *dst_areas, @@ -764,6 +766,7 @@ static int snd_pcm_rate_init(snd_pcm_t * assert(0); } rate->last_commit_ptr = 0; + rate->start_pending = 0; return 0; } @@ -1052,7 +1055,7 @@ static int snd_pcm_rate_commit_area(snd_ xfer = cont; if (xfer == slave_size) - return 1; + goto commit_done; /* commit second fragment */ cont = slave_size - cont; @@ -1080,6 +1083,13 @@ static int snd_pcm_rate_commit_area(snd_ return 0; } } + + commit_done: + if (rate->start_pending) { + /* we have pending start-trigger. let's issue it now */ + snd_pcm_start(rate->gen.slave); + rate->start_pending = 0; + } return 1; } @@ -1338,6 +1348,41 @@ static int snd_pcm_rate_drain(snd_pcm_t return snd_pcm_drain(rate->gen.slave); } +static snd_pcm_state_t snd_pcm_rate_state(snd_pcm_t *pcm) +{ + snd_pcm_rate_t *rate = pcm->private_data; + if (rate->start_pending) /* pseudo-state */ + return SND_PCM_STATE_RUNNING; + return snd_pcm_state(rate->gen.slave); +} + + +static int snd_pcm_rate_start(snd_pcm_t *pcm) +{ + snd_pcm_rate_t *rate = pcm->private_data; + snd_pcm_uframes_t avail; + struct timeval tv; + + if (pcm->stream == SND_PCM_STREAM_CAPTURE) + return snd_pcm_start(rate->gen.slave); + + if (snd_pcm_state(rate->gen.slave) != SND_PCM_STATE_PREPARED) + return -EBADFD; + + gettimeofday(&tv, 0); + rate->trigger_tstamp.tv_sec = tv.tv_sec; + rate->trigger_tstamp.tv_nsec = tv.tv_usec * 1000L; + + avail = snd_pcm_mmap_playback_hw_avail(rate->gen.slave); + if (avail == 0) { + /* postpone the trigger since we have no data committed yet */ + rate->start_pending = 1; + return 0; + } + rate->start_pending = 0; + return snd_pcm_start(rate->gen.slave); +} + static int snd_pcm_rate_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_rate_t *rate = pcm->private_data; @@ -1351,6 +1396,11 @@ static int snd_pcm_rate_status(snd_pcm_t snd_atomic_read_ok(&ratom); return err; } + if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { + if (rate->start_pending) + status->state = SND_PCM_STATE_RUNNING; + status->trigger_tstamp = rate->trigger_tstamp; + } snd_pcm_rate_sync_hwptr(pcm); status->appl_ptr = *pcm->appl.ptr; status->hw_ptr = *pcm->hw.ptr; @@ -1389,12 +1439,12 @@ static void snd_pcm_rate_dump(snd_pcm_t static snd_pcm_fast_ops_t snd_pcm_rate_fast_ops = { .status = snd_pcm_rate_status, - .state = snd_pcm_generic_state, + .state = snd_pcm_rate_state, .hwsync = snd_pcm_rate_hwsync, .delay = snd_pcm_rate_delay, .prepare = snd_pcm_rate_prepare, .reset = snd_pcm_rate_reset, - .start = snd_pcm_generic_start, + .start = snd_pcm_rate_start, .drop = snd_pcm_generic_drop, .drain = snd_pcm_rate_drain, .pause = snd_pcm_generic_pause, ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Remember to have fun...