The commit
1a9bd0f04481 ("pcm: direct: Fix for sync issue on xrun
recover") introduced a new field "recoveries" in
snd_pcm_direct_share_t. Unfortunately this caused two issues:
- It changed the size of the struct which is used as the magic key
- The struct size differs between 32bit and 64bit due to alignment
The former brought the incompatibility with the older alsa-lib,
e.g. when you run an app with an older alsa-lib via LD_PRELOAD, it
doesn't work any longer.
The latter is more serious, it disallows running 32bit apps dmix with
64bit together.
As a workaround, put recoveries field to the unused field
"s.xfer_align", so that the struct is in an old form. This makes the
dmix again binary-compatible with 1.1.3 and older versions, and also
fix the incompatibility between 32/64 bits.
This is a one-time workaround, and we may need to reconsider more
about a breakage in future...
Fixes:
1a9bd0f04481 ("pcm: direct: Fix for sync issue on xrun recover")
Reported-and-tested-by: Cheng Sun <chengsun9@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
- direct->shmptr->recoveries++;
+ direct->shmptr->s.recoveries++;
semerr = snd_pcm_direct_semaphore_up(direct,
DIRECT_IPC_SEM_CLIENT);
if (semerr < 0) {
semerr = snd_pcm_direct_semaphore_up(direct,
DIRECT_IPC_SEM_CLIENT);
if (semerr < 0) {
*/
int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm)
{
*/
int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm)
{
- if (direct->shmptr->recoveries != direct->recoveries) {
+ if (direct->shmptr->s.recoveries != direct->recoveries) {
/* no matter how many xruns we missed -
* so don't increment but just update to actual counter
*/
/* no matter how many xruns we missed -
* so don't increment but just update to actual counter
*/
- direct->recoveries = direct->shmptr->recoveries;
+ direct->recoveries = direct->shmptr->s.recoveries;
pcm->fast_ops->drop(pcm);
/* trigger_tstamp update is missing in drop callbacks */
gettimestamp(&direct->trigger_tstamp, pcm->tstamp_type);
pcm->fast_ops->drop(pcm);
/* trigger_tstamp update is missing in drop callbacks */
gettimestamp(&direct->trigger_tstamp, pcm->tstamp_type);
dmix->slave_buffer_size = spcm->buffer_size;
dmix->slave_period_size = dmix->shmptr->s.period_size;
dmix->slave_boundary = spcm->boundary;
dmix->slave_buffer_size = spcm->buffer_size;
dmix->slave_period_size = dmix->shmptr->s.period_size;
dmix->slave_boundary = spcm->boundary;
- dmix->recoveries = dmix->shmptr->recoveries;
+ dmix->recoveries = dmix->shmptr->s.recoveries;
ret = snd_pcm_mmap(spcm);
if (ret < 0) {
ret = snd_pcm_mmap(spcm);
if (ret < 0) {
char socket_name[256]; /* name of communication socket */
snd_pcm_type_t type; /* PCM type (currently only hw) */
int use_server;
char socket_name[256]; /* name of communication socket */
snd_pcm_type_t type; /* PCM type (currently only hw) */
int use_server;
- unsigned int recoveries; /* no of executed recoveries on slave*/
struct {
unsigned int format;
snd_interval_t rate;
struct {
unsigned int format;
snd_interval_t rate;
unsigned int stop_threshold;
unsigned int silence_threshold;
unsigned int silence_size;
unsigned int stop_threshold;
unsigned int silence_threshold;
unsigned int silence_size;
- unsigned int xfer_align; /* not used */
+ unsigned int recoveries; /* no of executed recoveries on slave*/
unsigned long long boundary;
unsigned int info;
unsigned int msbits;
unsigned long long boundary;
unsigned int info;
unsigned int msbits;