Accepting request 163432 from home:tiwai:branches:multimedia:libs

- Backport upstream fixes:
  0058-control-pcm-implement-snd_ctl_abort-and-snd_pcm_abor.patch
  0059-all-places-doxygen-cleanups.patch
  0060-pcm-direct-plugins-do-more-safe-IPC-semaphore-handli.patch
- Fix segfault with openal-soft (bnc#814250):
  0061-Clean-up-dlobj-cache-only-when-no-user-is-present.patch
  0062-Optimize-NULL-check-in-snd_dlobj_cache_put.patch

OBS-URL: https://build.opensuse.org/request/show/163432
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=128
This commit is contained in:
Takashi Iwai 2013-04-09 13:38:22 +00:00 committed by Git OBS Bridge
parent 96042eddda
commit 5ed110dffb
7 changed files with 931 additions and 0 deletions

View File

@ -0,0 +1,143 @@
From e23fb2c4de29b24c28f0c609521faa28d948a05b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Mon, 8 Apr 2013 13:28:03 +0200
Subject: [PATCH] control, pcm: implement snd_ctl_abort() and snd_pcm_abort()
functions
Upon an interrupt, it is necessary to abort the wait loops with the EINTR
error code. Introduce snd_*_abort() functions to handle this case.
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
include/control.h | 2 ++
include/pcm.h | 3 +++
src/control/control.c | 2 +-
src/control/control_local.h | 2 ++
src/control/hcontrol.c | 2 +-
src/pcm/pcm.c | 8 ++++++--
src/pcm/pcm_local.h | 2 ++
7 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/include/control.h b/include/control.h
index e840835..27fe2ac 100644
--- a/include/control.h
+++ b/include/control.h
@@ -234,6 +234,7 @@ int snd_ctl_open_lconf(snd_ctl_t **ctl, const char *name, int mode, snd_config_t
int snd_ctl_open_fallback(snd_ctl_t **ctl, snd_config_t *root, const char *name, const char *orig_name, int mode);
int snd_ctl_close(snd_ctl_t *ctl);
int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock);
+static inline int snd_ctl_abort(snd_ctl_t *ctl) { return snd_ctl_nonblock(ctl, 2); }
int snd_async_add_ctl_handler(snd_async_handler_t **handler, snd_ctl_t *ctl,
snd_async_callback_t callback, void *private_data);
snd_ctl_t *snd_async_handler_get_ctl(snd_async_handler_t *handler);
@@ -531,6 +532,7 @@ int snd_hctl_open(snd_hctl_t **hctl, const char *name, int mode);
int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl);
int snd_hctl_close(snd_hctl_t *hctl);
int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock);
+static inline int snd_hctl_abort(snd_hctl_t *hctl) { return snd_hctl_nonblock(hctl, 2); }
int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl);
int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space);
int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
diff --git a/include/pcm.h b/include/pcm.h
index 2235678..549d629 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -314,6 +314,8 @@ typedef long snd_pcm_sframes_t;
#define SND_PCM_NONBLOCK 0x00000001
/** Async notification (flag for open mode) \hideinitializer */
#define SND_PCM_ASYNC 0x00000002
+/** In an abort state (internal, not allowed for open) */
+#define SND_PCM_ABORT 0x00008000
/** Disable automatic (but not forced!) rate resamplinig */
#define SND_PCM_NO_AUTO_RESAMPLE 0x00010000
/** Disable automatic (but not forced!) channel conversion */
@@ -437,6 +439,7 @@ int snd_pcm_poll_descriptors_count(snd_pcm_t *pcm);
int snd_pcm_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
int snd_pcm_poll_descriptors_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock);
+static inline int snd_pcm_abort(snd_pcm_t *pcm) { return snd_pcm_nonblock(pcm, 2); }
int snd_async_add_pcm_handler(snd_async_handler_t **handler, snd_pcm_t *pcm,
snd_async_callback_t callback, void *private_data);
snd_pcm_t *snd_async_handler_get_pcm(snd_async_handler_t *handler);
diff --git a/src/control/control.c b/src/control/control.c
index 66277ef..5687ce1 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -103,7 +103,7 @@ int snd_ctl_close(snd_ctl_t *ctl)
/**
* \brief set nonblock mode
* \param ctl CTL handle
- * \param nonblock 0 = block, 1 = nonblock mode
+ * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort
* \return 0 on success otherwise a negative error code
*/
int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock)
diff --git a/src/control/control_local.h b/src/control/control_local.h
index 49150d8..9594ae5 100644
--- a/src/control/control_local.h
+++ b/src/control/control_local.h
@@ -98,3 +98,5 @@ int _snd_ctl_poll_descriptor(snd_ctl_t *ctl);
int snd_ctl_hw_open(snd_ctl_t **handle, const char *name, int card, int mode);
int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname, const char *sname, int mode);
int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid);
+
+#define CTLINABORT(x) ((x)->nonblock == 2)
diff --git a/src/control/hcontrol.c b/src/control/hcontrol.c
index ee1d907..7645c57 100644
--- a/src/control/hcontrol.c
+++ b/src/control/hcontrol.c
@@ -696,7 +696,7 @@ int snd_hctl_wait(snd_hctl_t *hctl, int timeout)
pollio = 0;
err_poll = poll(pfd, npfds, timeout);
if (err_poll < 0) {
- if (errno == EINTR)
+ if (errno == EINTR && !CTLINABORT(hctl->ctl))
continue;
return -errno;
}
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index 0868dd5..38febb9 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -716,7 +716,7 @@ int snd_pcm_close(snd_pcm_t *pcm)
/**
* \brief set nonblock mode
* \param pcm PCM handle
- * \param nonblock 0 = block, 1 = nonblock mode
+ * \param nonblock 0 = block, 1 = nonblock mode, 2 = abort
* \return 0 on success otherwise a negative error code
*/
int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
@@ -725,6 +725,10 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
assert(pcm);
if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
return err;
+ if (nonblock == 2) {
+ pcm->mode |= SND_PCM_ABORT;
+ return 0;
+ }
if (nonblock)
pcm->mode |= SND_PCM_NONBLOCK;
else {
@@ -2401,7 +2405,7 @@ int snd_pcm_wait_nocheck(snd_pcm_t *pcm, int timeout)
do {
err_poll = poll(pfd, npfds, timeout);
if (err_poll < 0) {
- if (errno == EINTR)
+ if (errno == EINTR && !PCMINABORT(pcm))
continue;
return -errno;
}
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index 63b9036..e1c0baa 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -1006,3 +1006,5 @@ static inline void sw_set_period_event(snd_pcm_sw_params_t *params, int val)
{
params->reserved[sizeof(params->reserved) / sizeof(params->reserved[0]) - 1] = val;
}
+
+#define PCMINABORT(pcm) (((pcm)->mode & SND_PCM_ABORT) != 0)
--
1.8.2.1

View File

@ -0,0 +1,567 @@
From b6eb0f9bfddb836fcc366d81f07ba62e46c95ccf Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Mon, 8 Apr 2013 16:42:24 +0200
Subject: [PATCH] all places: doxygen cleanups
I see no errors with these changes using doxygen 1.8.1.1 .
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
doc/index.doxygen | 2 +-
include/control_external.h | 7 +++-
include/error.h | 1 +
include/mixer.h | 2 +-
include/pcm.h | 82 +++++++++++++++++++++++-----------------------
include/pcm_extplug.h | 5 +++
include/pcm_ioplug.h | 5 +++
include/seq_event.h | 10 ++++--
include/use-case.h | 81 +++++++++++++++++++++++----------------------
src/conf.c | 2 ++
src/control/control.c | 4 +--
src/control/ctlparse.c | 1 +
src/error.c | 7 ++++
src/mixer/mixer.c | 2 +-
src/ucm/main.c | 36 ++++++++++----------
15 files changed, 141 insertions(+), 106 deletions(-)
diff --git a/doc/index.doxygen b/doc/index.doxygen
index f76cc10..45aa68a 100644
--- a/doc/index.doxygen
+++ b/doc/index.doxygen
@@ -1,4 +1,4 @@
-/*! \page Index Preamble and License
+/*! \mainpage Index Preamble and License
\author Jaroslav Kysela <perex@perex.cz>
\author Abramo Bagnara <abramo@alsa-project.org>
diff --git a/include/control_external.h b/include/control_external.h
index e98f4d6..12958e7 100644
--- a/include/control_external.h
+++ b/include/control_external.h
@@ -60,6 +60,11 @@ typedef struct snd_ctl_ext snd_ctl_ext_t;
typedef struct snd_ctl_ext_callback snd_ctl_ext_callback_t;
/** Key to access a control pointer */
typedef unsigned long snd_ctl_ext_key_t;
+#ifdef DOC_HIDDEN
+/* redefine typedef's for stupid doxygen */
+typedef snd_ctl_ext snd_ctl_ext_t;
+typedef snd_ctl_ext_callback snd_ctl_ext_callback_t;
+#endif
/** Callback to handle TLV commands. */
typedef int (snd_ctl_ext_tlv_rw_t)(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key, int op_flag, unsigned int numid,
unsigned int *tlv, unsigned int tlv_size);
@@ -138,7 +143,7 @@ struct snd_ctl_ext {
} tlv;
};
-/** Callback table of ext */
+/** Callback table of ext. */
struct snd_ctl_ext_callback {
/**
* close the control handle; optional
diff --git a/include/error.h b/include/error.h
index 256cd5f..38ee070 100644
--- a/include/error.h
+++ b/include/error.h
@@ -74,6 +74,7 @@ extern int snd_lib_error_set_handler(snd_lib_error_handler_t handler);
}
#endif
+/** Local error handler function type */
typedef void (*snd_local_error_handler_t)(const char *file, int line,
const char *func, int err,
const char *fmt, va_list arg);
diff --git a/include/mixer.h b/include/mixer.h
index 58256a6..066d978 100644
--- a/include/mixer.h
+++ b/include/mixer.h
@@ -154,7 +154,7 @@ void *snd_mixer_class_get_private(const snd_mixer_class_t *class_);
snd_mixer_compare_t snd_mixer_class_get_compare(const snd_mixer_class_t *class_);
int snd_mixer_class_set_event(snd_mixer_class_t *class_, snd_mixer_event_t event);
int snd_mixer_class_set_private(snd_mixer_class_t *class_, void *private_data);
-int snd_mixer_class_set_private_free(snd_mixer_class_t *class_, void (*private_free)(snd_mixer_class_t *class_));
+int snd_mixer_class_set_private_free(snd_mixer_class_t *class_, void (*private_free)(snd_mixer_class_t *));
int snd_mixer_class_set_compare(snd_mixer_class_t *class_, snd_mixer_compare_t compare);
/**
diff --git a/include/pcm.h b/include/pcm.h
index 549d629..d94ba90 100644
--- a/include/pcm.h
+++ b/include/pcm.h
@@ -491,43 +491,43 @@ enum snd_pcm_chmap_type {
/** channel positions */
enum snd_pcm_chmap_position {
- SND_CHMAP_UNKNOWN = 0, /** unspecified */
- SND_CHMAP_NA, /** N/A, silent */
- SND_CHMAP_MONO, /** mono stream */
- SND_CHMAP_FL, /** front left */
- SND_CHMAP_FR, /** front right */
- SND_CHMAP_RL, /** rear left */
- SND_CHMAP_RR, /** rear right */
- SND_CHMAP_FC, /** front center */
- SND_CHMAP_LFE, /** LFE */
- SND_CHMAP_SL, /** side left */
- SND_CHMAP_SR, /** side right */
- SND_CHMAP_RC, /** rear center */
- SND_CHMAP_FLC, /** front left center */
- SND_CHMAP_FRC, /** front right center */
- SND_CHMAP_RLC, /** rear left center */
- SND_CHMAP_RRC, /** rear right center */
- SND_CHMAP_FLW, /** front left wide */
- SND_CHMAP_FRW, /** front right wide */
- SND_CHMAP_FLH, /** front left high */
- SND_CHMAP_FCH, /** front center high */
- SND_CHMAP_FRH, /** front right high */
- SND_CHMAP_TC, /** top center */
- SND_CHMAP_TFL, /** top front left */
- SND_CHMAP_TFR, /** top front right */
- SND_CHMAP_TFC, /** top front center */
- SND_CHMAP_TRL, /** top rear left */
- SND_CHMAP_TRR, /** top rear right */
- SND_CHMAP_TRC, /** top rear center */
- SND_CHMAP_TFLC, /* top front left center */
- SND_CHMAP_TFRC, /* top front right center */
- SND_CHMAP_TSL, /* top side left */
- SND_CHMAP_TSR, /* top side right */
- SND_CHMAP_LLFE, /* left LFE */
- SND_CHMAP_RLFE, /* right LFE */
- SND_CHMAP_BC, /* bottom center */
- SND_CHMAP_BLC, /* bottom left center */
- SND_CHMAP_BRC, /* bottom right center */
+ SND_CHMAP_UNKNOWN = 0, /**< unspecified */
+ SND_CHMAP_NA, /**< N/A, silent */
+ SND_CHMAP_MONO, /**< mono stream */
+ SND_CHMAP_FL, /**< front left */
+ SND_CHMAP_FR, /**< front right */
+ SND_CHMAP_RL, /**< rear left */
+ SND_CHMAP_RR, /**< rear right */
+ SND_CHMAP_FC, /**< front center */
+ SND_CHMAP_LFE, /**< LFE */
+ SND_CHMAP_SL, /**< side left */
+ SND_CHMAP_SR, /**< side right */
+ SND_CHMAP_RC, /**< rear center */
+ SND_CHMAP_FLC, /**< front left center */
+ SND_CHMAP_FRC, /**< front right center */
+ SND_CHMAP_RLC, /**< rear left center */
+ SND_CHMAP_RRC, /**< rear right center */
+ SND_CHMAP_FLW, /**< front left wide */
+ SND_CHMAP_FRW, /**< front right wide */
+ SND_CHMAP_FLH, /**< front left high */
+ SND_CHMAP_FCH, /**< front center high */
+ SND_CHMAP_FRH, /**< front right high */
+ SND_CHMAP_TC, /**< top center */
+ SND_CHMAP_TFL, /**< top front left */
+ SND_CHMAP_TFR, /**< top front right */
+ SND_CHMAP_TFC, /**< top front center */
+ SND_CHMAP_TRL, /**< top rear left */
+ SND_CHMAP_TRR, /**< top rear right */
+ SND_CHMAP_TRC, /**< top rear center */
+ SND_CHMAP_TFLC, /**< top front left center */
+ SND_CHMAP_TFRC, /**< top front right center */
+ SND_CHMAP_TSL, /**< top side left */
+ SND_CHMAP_TSR, /**< top side right */
+ SND_CHMAP_LLFE, /**< left LFE */
+ SND_CHMAP_RLFE, /**< right LFE */
+ SND_CHMAP_BC, /**< bottom center */
+ SND_CHMAP_BLC, /**< bottom left center */
+ SND_CHMAP_BRC, /**< bottom right center */
SND_CHMAP_LAST = SND_CHMAP_BRC,
};
@@ -541,14 +541,14 @@ enum snd_pcm_chmap_position {
/** the channel map header */
typedef struct snd_pcm_chmap {
- unsigned int channels; /** number of channels */
- unsigned int pos[0]; /** channel position array */
+ unsigned int channels; /**< number of channels */
+ unsigned int pos[0]; /**< channel position array */
} snd_pcm_chmap_t;
/** the header of array items returned from snd_pcm_query_chmaps() */
typedef struct snd_pcm_chmap_query {
- enum snd_pcm_chmap_type type; /** channel map type */
- snd_pcm_chmap_t map; /** available channel map */
+ enum snd_pcm_chmap_type type; /**< channel map type */
+ snd_pcm_chmap_t map; /**< available channel map */
} snd_pcm_chmap_query_t;
diff --git a/include/pcm_extplug.h b/include/pcm_extplug.h
index 4eb10c7..884f322 100644
--- a/include/pcm_extplug.h
+++ b/include/pcm_extplug.h
@@ -49,6 +49,11 @@ enum {
typedef struct snd_pcm_extplug snd_pcm_extplug_t;
/** Callback table of extplug */
typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
+#ifdef DOC_HIDDEN
+/* redefine typedefs for stupid doxygen */
+typedef snd_pcm_extplug snd_pcm_extplug_t;
+typedef snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
+#endif
/*
* Protocol version
diff --git a/include/pcm_ioplug.h b/include/pcm_ioplug.h
index 25202fd..e529e6a 100644
--- a/include/pcm_ioplug.h
+++ b/include/pcm_ioplug.h
@@ -54,6 +54,11 @@ enum {
typedef struct snd_pcm_ioplug snd_pcm_ioplug_t;
/** Callback table of ioplug */
typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
+#ifdef DOC_HIDDEN
+/* redefine typedefs for stupid doxygen */
+typedef snd_pcm_ioplug snd_pcm_ioplug_t;
+typedef snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
+#endif
/*
* bit flags for additional conditions
diff --git a/include/seq_event.h b/include/seq_event.h
index 583f1d0..6bd0de3 100644
--- a/include/seq_event.h
+++ b/include/seq_event.h
@@ -254,10 +254,16 @@ typedef struct snd_seq_ev_raw32 {
} snd_seq_ev_raw32_t;
/** external stored data */
-typedef struct snd_seq_ev_ext {
+struct snd_seq_ev_ext {
unsigned int len; /**< length of data */
void *ptr; /**< pointer to data (note: can be 64-bit) */
-} __attribute__((packed)) snd_seq_ev_ext_t;
+} __attribute__((packed));
+/** external stored data */
+typedef struct snd_seq_ev_ext snd_seq_ev_ext_t;
+#ifdef DOC_HIDDEN
+/* redefine typedef for stupid doxygen */
+typedef snd_seq_ev_ext snd_seq_ev_ext_t;
+#endif
/** Result events */
typedef struct snd_seq_result {
diff --git a/include/use-case.h b/include/use-case.h
index c37c842..defd4ea 100644
--- a/include/use-case.h
+++ b/include/use-case.h
@@ -49,7 +49,8 @@ extern "C" {
* \{
*/
-/**
+/*! \page Usecase ALSA Use Case Interface
+ *
* ALSA Use Case Interface
*
* The use case manager works by configuring the sound card ALSA kcontrols to
@@ -96,15 +97,15 @@ extern "C" {
* case verb will configure the audio hardware for HiFi Music playback
* and capture.
*/
-#define SND_USE_CASE_VERB_INACTIVE "Inactive"
-#define SND_USE_CASE_VERB_HIFI "HiFi"
-#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power"
-#define SND_USE_CASE_VERB_VOICE "Voice"
-#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power"
-#define SND_USE_CASE_VERB_VOICECALL "Voice Call"
-#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP"
-#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio"
-#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio"
+#define SND_USE_CASE_VERB_INACTIVE "Inactive" /**< Inactive Verb */
+#define SND_USE_CASE_VERB_HIFI "HiFi" /**< HiFi Verb */
+#define SND_USE_CASE_VERB_HIFI_LOW_POWER "HiFi Low Power" /**< HiFi Low Power Verb */
+#define SND_USE_CASE_VERB_VOICE "Voice" /**< Voice Verb */
+#define SND_USE_CASE_VERB_VOICE_LOW_POWER "Voice Low Power" /**< Voice Low Power Verb */
+#define SND_USE_CASE_VERB_VOICECALL "Voice Call" /**< Voice Call Verb */
+#define SND_USE_CASE_VERB_IP_VOICECALL "Voice Call IP" /**< Voice Call IP Verb */
+#define SND_USE_CASE_VERB_ANALOG_RADIO "FM Analog Radio" /**< FM Analog Radio Verb */
+#define SND_USE_CASE_VERB_DIGITAL_RADIO "FM Digital Radio" /**< FM Digital Radio Verb */
/* add new verbs to end of list */
@@ -114,16 +115,16 @@ extern "C" {
* Physical system devices the render and capture audio. Devices can be OR'ed
* together to support audio on simultaneous devices.
*/
-#define SND_USE_CASE_DEV_NONE "None"
-#define SND_USE_CASE_DEV_SPEAKER "Speaker"
-#define SND_USE_CASE_DEV_LINE "Line"
-#define SND_USE_CASE_DEV_HEADPHONES "Headphones"
-#define SND_USE_CASE_DEV_HEADSET "Headset"
-#define SND_USE_CASE_DEV_HANDSET "Handset"
-#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth"
-#define SND_USE_CASE_DEV_EARPIECE "Earpiece"
-#define SND_USE_CASE_DEV_SPDIF "SPDIF"
-#define SND_USE_CASE_DEV_HDMI "HDMI"
+#define SND_USE_CASE_DEV_NONE "None" /**< None Device */
+#define SND_USE_CASE_DEV_SPEAKER "Speaker" /**< Speaker Device */
+#define SND_USE_CASE_DEV_LINE "Line" /**< Line Device */
+#define SND_USE_CASE_DEV_HEADPHONES "Headphones" /**< Headphones Device */
+#define SND_USE_CASE_DEV_HEADSET "Headset" /**< Headset Device */
+#define SND_USE_CASE_DEV_HANDSET "Handset" /**< Handset Device */
+#define SND_USE_CASE_DEV_BLUETOOTH "Bluetooth" /**< Bluetooth Device */
+#define SND_USE_CASE_DEV_EARPIECE "Earpiece" /**< Earpiece Device */
+#define SND_USE_CASE_DEV_SPDIF "SPDIF" /**< SPDIF Device */
+#define SND_USE_CASE_DEV_HDMI "HDMI" /**< HDMI Device */
/* add new devices to end of list */
@@ -145,12 +146,12 @@ extern "C" {
* 3. Call snd_use_case_get("PlaybackPCM") to get ALSA PCM sink name for
* ringtone pcm data.
*/
-#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice"
-#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music"
-#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music"
-#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice"
-#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone"
-#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference"
+#define SND_USE_CASE_MOD_CAPTURE_VOICE "Capture Voice" /**< Capture Voice Modifier */
+#define SND_USE_CASE_MOD_CAPTURE_MUSIC "Capture Music" /**< Capture Music Modifier */
+#define SND_USE_CASE_MOD_PLAY_MUSIC "Play Music" /**< Play Music Modifier */
+#define SND_USE_CASE_MOD_PLAY_VOICE "Play Voice" /**< Play Voice Modifier */
+#define SND_USE_CASE_MOD_PLAY_TONE "Play Tone" /**< Play Tone Modifier */
+#define SND_USE_CASE_MOD_ECHO_REF "Echo Reference" /**< Echo Reference Modifier */
/* add new modifiers to end of list */
@@ -162,9 +163,9 @@ extern "C" {
* audio driver in order to lower power consumption.
*
*/
-#define SND_USE_CASE_TQ_MUSIC "Music"
-#define SND_USE_CASE_TQ_VOICE "Voice"
-#define SND_USE_CASE_TQ_TONES "Tones"
+#define SND_USE_CASE_TQ_MUSIC "Music" /**< Music Tone Quality */
+#define SND_USE_CASE_TQ_VOICE "Voice" /**< Voice Tone Quality */
+#define SND_USE_CASE_TQ_TONES "Tones" /**< Tones Tone Quality */
/** use case container */
typedef struct snd_use_case_mgr snd_use_case_mgr_t;
@@ -197,16 +198,16 @@ int snd_use_case_free_list(const char *list[], int items);
* (in pair cardname+comment)
* _verbs - get verb list
* (in pair verb+comment)
- * _devices[/<verb>] - get list of supported devices
+ * _devices[/{verb}] - get list of supported devices
* (in pair device+comment)
- * _modifiers[/<verb>]- get list of supported modifiers
+ * _modifiers[/{verb}]- get list of supported modifiers
* (in pair modifier+comment)
- * TQ[/<verb>] - get list of TQ identifiers
+ * TQ[/{verb}] - get list of TQ identifiers
* _enadevs - get list of enabled devices
* _enamods - get list of enabled modifiers
*
- * _supporteddevs/<modifier>|<device>[/<verb>] - list of supported devices
- * _conflictingdevs/<modifier>|<device>[/<verb>] - list of conflicting devices
+ * _supporteddevs/{modifier}|{device}[/{verb}] - list of supported devices
+ * _conflictingdevs/{modifier}|{device}[/{verb}] - list of conflicting devices
* Note that at most one of the supported/conflicting devs lists has
* any entries, and when neither is present, all devices are supported.
*
@@ -230,8 +231,8 @@ int snd_use_case_get_list(snd_use_case_mgr_t *uc_mgr,
* NULL - return current card
* _verb - return current verb
*
- * [=]<NAME>[/[<modifier>|</device>][/<verb>]]
- * - value identifier <NAME>
+ * [=]{NAME}[/[{modifier}|{/device}][/{verb}]]
+ * - value identifier {NAME}
* - Search starts at given modifier or device if any,
* else at a verb
* - Search starts at given verb if any,
@@ -281,8 +282,8 @@ int snd_use_case_get(snd_use_case_mgr_t *uc_mgr,
* \return Zero if success, otherwise a negative error code
*
* Known identifiers:
- * _devstatus/<device> - return status for given device
- * _modstatus/<modifier> - return status for given modifier
+ * _devstatus/{device} - return status for given device
+ * _modstatus/{modifier} - return status for given modifier
*/
int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
const char *identifier,
@@ -299,13 +300,13 @@ int snd_use_case_geti(snd_use_case_mgr_t *uc_mgr,
* _verb - set current verb = value
* _enadev - enable given device = value
* _disdev - disable given device = value
- * _swdev/<old_device> - new_device = value
+ * _swdev/{old_device} - new_device = value
* - disable old_device and then enable new_device
* - if old_device is not enabled just return
* - check transmit sequence firstly
* _enamod - enable given modifier = value
* _dismod - disable given modifier = value
- * _swmod/<old_modifier> - new_modifier = value
+ * _swmod/{old_modifier} - new_modifier = value
* - disable old_modifier and then enable new_modifier
* - if old_modifier is not enabled just return
* - check transmit sequence firstly
diff --git a/src/conf.c b/src/conf.c
index 4ba5863..bfed1c4 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -3505,11 +3505,13 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t
struct dirent **namelist;
int n;
+#ifndef DOC_HIDDEN
#ifdef _GNU_SOURCE
#define SORTFUNC versionsort
#else
#define SORTFUNC alphasort
#endif
+#endif
n = scandir(fi[idx].name, &namelist, config_filename_filter, SORTFUNC);
if (n > 0) {
int j;
diff --git a/src/control/control.c b/src/control/control.c
index 5687ce1..d66ed75 100644
--- a/src/control/control.c
+++ b/src/control/control.c
@@ -2323,8 +2323,8 @@ void snd_ctl_elem_value_copy(snd_ctl_elem_value_t *dst, const snd_ctl_elem_value
/**
* \brief compare one #snd_ctl_elem_value_t to another
- * \param dst pointer to destination
- * \param src pointer to source
+ * \param left pointer to first value
+ * \param right pointer to second value
* \return 0 on match, less than or greater than otherwise, see memcmp
*/
int snd_ctl_elem_value_compare(snd_ctl_elem_value_t *left, const snd_ctl_elem_value_t *right)
diff --git a/src/control/ctlparse.c b/src/control/ctlparse.c
index b0c4ef3..c442c44 100644
--- a/src/control/ctlparse.c
+++ b/src/control/ctlparse.c
@@ -297,6 +297,7 @@ static int get_ctl_enum_item_index(snd_ctl_t *handle,
/**
* \brief parse ASCII string as CTL element value
+ * \param handle CTL handle
* \param dst destination CTL element value
* \param info CTL element info structure
* \param value source ASCII string
diff --git a/src/error.c b/src/error.c
index 85cea5e..4566783 100644
--- a/src/error.c
+++ b/src/error.c
@@ -60,14 +60,21 @@ const char *snd_strerror(int errnum)
return snd_error_codes[errnum];
}
+#ifndef DOC_HIDDEN
#ifdef HAVE___THREAD
#define TLS_PFX __thread
#else
#define TLS_PFX /* NOP */
#endif
+#endif
static TLS_PFX snd_local_error_handler_t local_error = NULL;
+/**
+ * \brief Install local error handler
+ * \param func The local error handler function
+ * \retval Previous local error handler function
+ */
snd_local_error_handler_t snd_lib_error_set_local(snd_local_error_handler_t func)
{
snd_local_error_handler_t old = local_error;
diff --git a/src/mixer/mixer.c b/src/mixer/mixer.c
index 8deceac..56e023d 100644
--- a/src/mixer/mixer.c
+++ b/src/mixer/mixer.c
@@ -1062,7 +1062,7 @@ int snd_mixer_class_set_private(snd_mixer_class_t *obj, void *private_data)
* \param private_free Mixer class private data free callback
* \return zero if success, otherwise a negative error code
*/
-int snd_mixer_class_set_private_free(snd_mixer_class_t *obj, void (*private_free)(snd_mixer_class_t *class))
+int snd_mixer_class_set_private_free(snd_mixer_class_t *obj, void (*private_free)(snd_mixer_class_t *))
{
assert(obj);
obj->private_free = private_free;
diff --git a/src/ucm/main.c b/src/ucm/main.c
index d8b8ada..d38b7fa 100644
--- a/src/ucm/main.c
+++ b/src/ucm/main.c
@@ -702,42 +702,42 @@ static int set_device(snd_use_case_mgr_t *uc_mgr,
* \param card_name name of card to open
* \return zero on success, otherwise a negative error code
*/
-int snd_use_case_mgr_open(snd_use_case_mgr_t **mgr,
+int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
const char *card_name)
{
- snd_use_case_mgr_t *uc_mgr;
+ snd_use_case_mgr_t *mgr;
int err;
/* create a new UCM */
- uc_mgr = calloc(1, sizeof(snd_use_case_mgr_t));
- if (uc_mgr == NULL)
+ mgr = calloc(1, sizeof(snd_use_case_mgr_t));
+ if (mgr == NULL)
return -ENOMEM;
- INIT_LIST_HEAD(&uc_mgr->verb_list);
- INIT_LIST_HEAD(&uc_mgr->default_list);
- INIT_LIST_HEAD(&uc_mgr->value_list);
- INIT_LIST_HEAD(&uc_mgr->active_modifiers);
- INIT_LIST_HEAD(&uc_mgr->active_devices);
- pthread_mutex_init(&uc_mgr->mutex, NULL);
-
- uc_mgr->card_name = strdup(card_name);
- if (uc_mgr->card_name == NULL) {
- free(uc_mgr);
+ INIT_LIST_HEAD(&mgr->verb_list);
+ INIT_LIST_HEAD(&mgr->default_list);
+ INIT_LIST_HEAD(&mgr->value_list);
+ INIT_LIST_HEAD(&mgr->active_modifiers);
+ INIT_LIST_HEAD(&mgr->active_devices);
+ pthread_mutex_init(&mgr->mutex, NULL);
+
+ mgr->card_name = strdup(card_name);
+ if (mgr->card_name == NULL) {
+ free(mgr);
return -ENOMEM;
}
/* get info on use_cases and verify against card */
- err = import_master_config(uc_mgr);
+ err = import_master_config(mgr);
if (err < 0) {
uc_error("error: failed to import %s use case configuration %d",
card_name, err);
goto err;
}
- *mgr = uc_mgr;
+ *uc_mgr = mgr;
return 0;
err:
- uc_mgr_free(uc_mgr);
+ uc_mgr_free(mgr);
return err;
}
@@ -973,10 +973,12 @@ static int get_conflicting_device_list(snd_use_case_mgr_t *uc_mgr,
return get_supcon_device_list(uc_mgr, list, name, DEVLIST_CONFLICTING);
}
+#ifndef DOC_HIDDEN
struct myvalue {
struct list_head list;
char *value;
};
+#endif
static int add_values(struct list_head *list,
const char *identifier,
--
1.8.2.1

View File

@ -0,0 +1,117 @@
From a6813c2d0e2fa4586122d23748033a8bab206b8b Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Tue, 9 Apr 2013 14:31:20 +0200
Subject: [PATCH] pcm: direct plugins: do more safe IPC semaphore handling
As reported dead-lock, do local lock counting and invoke abort() when
the lock counts do not match at close() time.
Reported-by: <mateen abdulmateen.shaikh@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/pcm/pcm_direct.h | 18 ++++++++++++++++--
src/pcm/pcm_dmix.c | 4 ++--
src/pcm/pcm_dshare.c | 9 +++++----
src/pcm/pcm_dsnoop.c | 9 +++++----
4 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h
index 1c35dcb..70c2c6a 100644
--- a/src/pcm/pcm_direct.h
+++ b/src/pcm/pcm_direct.h
@@ -122,6 +122,7 @@ struct snd_pcm_direct {
mode_t ipc_perm; /* IPC socket permissions */
int ipc_gid; /* IPC socket gid */
int semid; /* IPC global semaphore identification */
+ int locked[DIRECT_IPC_SEMS]; /* local lock counter */
int shmid; /* IPC global shared memory identification */
snd_pcm_direct_share_t *shmptr; /* pointer to shared memory area */
snd_pcm_t *spcm; /* slave PCM handle */
@@ -257,13 +258,26 @@ static inline int snd_pcm_direct_semaphore_discard(snd_pcm_direct_t *dmix)
static inline int snd_pcm_direct_semaphore_down(snd_pcm_direct_t *dmix, int sem_num)
{
struct sembuf op[2] = { { sem_num, 0, 0 }, { sem_num, 1, SEM_UNDO } };
- return semop(dmix->semid, op, 2);
+ int err = semop(dmix->semid, op, 2);
+ if (err == 0) dmix->locked[sem_num]++;
+ return err;
}
static inline int snd_pcm_direct_semaphore_up(snd_pcm_direct_t *dmix, int sem_num)
{
struct sembuf op = { sem_num, -1, SEM_UNDO | IPC_NOWAIT };
- return semop(dmix->semid, &op, 1);
+ int err = semop(dmix->semid, &op, 1);
+ if (err == 0) dmix->locked[sem_num]--;
+ return err;
+}
+
+static inline int snd_pcm_direct_semaphore_final(snd_pcm_direct_t *dmix, int sem_num)
+{
+ if (dmix->locked[sem_num] != 1) {
+ assert(dmix->locked[sem_num] != 1);
+ abort();
+ }
+ return snd_pcm_direct_semaphore_up(dmix, sem_num);
}
int snd_pcm_direct_shm_create_or_connect(snd_pcm_direct_t *dmix);
diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c
index 16dba14..2bd5d39 100644
--- a/src/pcm/pcm_dmix.c
+++ b/src/pcm/pcm_dmix.c
@@ -781,9 +781,9 @@ static int snd_pcm_dmix_close(snd_pcm_t *pcm)
shm_sum_discard(dmix);
if (snd_pcm_direct_shm_discard(dmix)) {
if (snd_pcm_direct_semaphore_discard(dmix))
- snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
+ snd_pcm_direct_semaphore_final(dmix, DIRECT_IPC_SEM_CLIENT);
} else
- snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT);
+ snd_pcm_direct_semaphore_final(dmix, DIRECT_IPC_SEM_CLIENT);
free(dmix->bindings);
pcm->private_data = NULL;
free(dmix);
diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index 1bdb670..5b32951 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -470,10 +470,11 @@ static int snd_pcm_dshare_close(snd_pcm_t *pcm)
snd_pcm_direct_server_discard(dshare);
if (dshare->client)
snd_pcm_direct_client_discard(dshare);
- if (snd_pcm_direct_shm_discard(dshare))
- snd_pcm_direct_semaphore_discard(dshare);
- else
- snd_pcm_direct_semaphore_up(dshare, DIRECT_IPC_SEM_CLIENT);
+ if (snd_pcm_direct_shm_discard(dshare)) {
+ if (snd_pcm_direct_semaphore_discard(dshare))
+ snd_pcm_direct_semaphore_final(dshare, DIRECT_IPC_SEM_CLIENT);
+ } else
+ snd_pcm_direct_semaphore_final(dshare, DIRECT_IPC_SEM_CLIENT);
free(dshare->bindings);
pcm->private_data = NULL;
free(dshare);
diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c
index ea07e04..055e4f4 100644
--- a/src/pcm/pcm_dsnoop.c
+++ b/src/pcm/pcm_dsnoop.c
@@ -391,10 +391,11 @@ static int snd_pcm_dsnoop_close(snd_pcm_t *pcm)
snd_pcm_direct_server_discard(dsnoop);
if (dsnoop->client)
snd_pcm_direct_client_discard(dsnoop);
- if (snd_pcm_direct_shm_discard(dsnoop))
- snd_pcm_direct_semaphore_discard(dsnoop);
- else
- snd_pcm_direct_semaphore_up(dsnoop, DIRECT_IPC_SEM_CLIENT);
+ if (snd_pcm_direct_shm_discard(dsnoop)) {
+ if (snd_pcm_direct_semaphore_discard(dsnoop))
+ snd_pcm_direct_semaphore_final(dsnoop, DIRECT_IPC_SEM_CLIENT);
+ } else
+ snd_pcm_direct_semaphore_final(dsnoop, DIRECT_IPC_SEM_CLIENT);
free(dsnoop->bindings);
pcm->private_data = NULL;
free(dsnoop);
--
1.8.2.1

View File

@ -0,0 +1,56 @@
From e79990ac5d09001c8c678feaed057e991ee8379e Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 9 Apr 2013 14:55:46 +0200
Subject: [PATCH] Clean up dlobj cache only when no user is present
Cleaning up the dlobj cache seems crashing some cases when the library
is used from another plugin like openal-soft. A simple workaround is
to do the cleanup only when really no user is left, i.e. after all
close calls.
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=814250
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/dlmisc.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/src/dlmisc.c b/src/dlmisc.c
index ecbbe8d..585c7f6 100644
--- a/src/dlmisc.c
+++ b/src/dlmisc.c
@@ -295,17 +295,24 @@ void snd_dlobj_cache_cleanup(void)
struct list_head *p, *npos;
struct dlobj_cache *c;
+ /* clean up caches only when really no user is present */
snd_dlobj_lock();
+ list_for_each(p, &pcm_dlobj_list) {
+ c = list_entry(p, struct dlobj_cache, list);
+ if (c->refcnt)
+ goto unlock;
+ }
+
list_for_each_safe(p, npos, &pcm_dlobj_list) {
c = list_entry(p, struct dlobj_cache, list);
- if (c->refcnt == 0) {
- list_del(p);
- snd_dlclose(c->dlobj);
- free((void *)c->name); /* shut up gcc warning */
- free((void *)c->lib); /* shut up gcc warning */
- free(c);
- }
+ list_del(p);
+ snd_dlclose(c->dlobj);
+ free((void *)c->name); /* shut up gcc warning */
+ free((void *)c->lib); /* shut up gcc warning */
+ free(c);
}
+
+ unlock:
snd_dlobj_unlock();
}
#endif
--
1.8.2.1

View File

@ -0,0 +1,27 @@
From 91de1212d0da0e52c64f7392f35e3c129d6bbce5 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai@suse.de>
Date: Tue, 9 Apr 2013 14:58:52 +0200
Subject: [PATCH] Optimize NULL check in snd_dlobj_cache_put()
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
src/dlmisc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/dlmisc.c b/src/dlmisc.c
index 585c7f6..3788382 100644
--- a/src/dlmisc.c
+++ b/src/dlmisc.c
@@ -275,6 +275,9 @@ int snd_dlobj_cache_put(void *func)
struct dlobj_cache *c;
unsigned int refcnt;
+ if (!func)
+ return -ENOENT;
+
snd_dlobj_lock();
list_for_each(p, &pcm_dlobj_list) {
c = list_entry(p, struct dlobj_cache, list);
--
1.8.2.1

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Tue Apr 9 15:04:10 CEST 2013 - tiwai@suse.de
- Backport upstream fixes:
0058-control-pcm-implement-snd_ctl_abort-and-snd_pcm_abor.patch
0059-all-places-doxygen-cleanups.patch
0060-pcm-direct-plugins-do-more-safe-IPC-semaphore-handli.patch
- Fix segfault with openal-soft (bnc#814250):
0061-Clean-up-dlobj-cache-only-when-no-user-is-present.patch
0062-Optimize-NULL-check-in-snd_dlobj_cache_put.patch
-------------------------------------------------------------------
Fri Apr 5 12:42:57 CEST 2013 - tiwai@suse.de

View File

@ -109,6 +109,11 @@ Patch54: 0054-snd_mixer_poll_descriptors_revents-should-loop-over-.patch
Patch55: 0055-pcm-fix-and-optimize-snd_pcm_areas_copy-function.patch
Patch56: 0056-USB-audio-Add-HP-Digital-Stereo-Headset-to-SPDIF-bla.patch
Patch57: 0057-pcm-fix-typo-should-be-SND_PCM_STATE_PREPARED.patch
Patch58: 0058-control-pcm-implement-snd_ctl_abort-and-snd_pcm_abor.patch
Patch59: 0059-all-places-doxygen-cleanups.patch
Patch60: 0060-pcm-direct-plugins-do-more-safe-IPC-semaphore-handli.patch
Patch61: 0061-Clean-up-dlobj-cache-only-when-no-user-is-present.patch
Patch62: 0062-Optimize-NULL-check-in-snd_dlobj_cache_put.patch
#
Patch99: alsa-lib-doxygen-avoid-crash-for-11.3.diff
Url: http://www.alsa-project.org/
@ -216,6 +221,11 @@ Architecture.
%patch55 -p1
%patch56 -p1
%patch57 -p1
%patch58 -p1
%patch59 -p1
%patch60 -p1
%patch61 -p1
%patch62 -p1
%if %suse_version == 1130
%patch99 -p1
%endif