diff options
author | Paul McLean <pmclean@google.com> | 2016-06-02 15:33:24 -0600 |
---|---|---|
committer | Paul McLean <pmclean@google.com> | 2016-06-02 15:33:24 -0600 |
commit | 994ac07b9699ea8d36855974314f86b66ee6ca86 (patch) | |
tree | 5c1545b19f7c59f01bdc841aa1a909affd141a1d | |
parent | dd01395ef1ac527f140c3b61449a948c413937d8 (diff) | |
download | libhardware-994ac07b9699ea8d36855974314f86b66ee6ca86.tar.gz |
replace naked pthread_mutex_ functions with semantics-explicit lock/unlock functions.
Bug: 29103653
Change-Id: Ic91f75f8653f7946790b8b433236fd918b41f3a6
-rw-r--r-- | modules/usbaudio/audio_hal.c | 183 |
1 files changed, 101 insertions, 82 deletions
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 07705ee5..10e0a755 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -81,11 +81,16 @@ struct audio_device { bool standby; }; +struct stream_lock { + pthread_mutex_t lock; /* see note below on mutex acquisition order */ + pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */ +}; + struct stream_out { struct audio_stream_out stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */ + struct stream_lock lock; + bool standby; struct audio_device *adev; /* hardware information - only using this for the lock */ @@ -111,8 +116,8 @@ struct stream_out { struct stream_in { struct audio_stream_in stream; - pthread_mutex_t lock; /* see note below on mutex acquisition order */ - pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by capture thread */ + struct stream_lock lock; + bool standby; struct audio_device *adev; /* hardware information - only using this for the lock */ @@ -136,32 +141,65 @@ struct stream_in { size_t conversion_buffer_size; /* in bytes */ }; +/* + * Locking Helpers + */ +/* + * NOTE: when multiple mutexes have to be acquired, always take the + * stream_in or stream_out mutex first, followed by the audio_device mutex. + * stream pre_lock is always acquired before stream lock to prevent starvation of control thread by + * higher priority playback or capture thread. + */ + +static void stream_lock_init(struct stream_lock *lock) { + pthread_mutex_init(&lock->lock, (const pthread_mutexattr_t *) NULL); + pthread_mutex_init(&lock->pre_lock, (const pthread_mutexattr_t *) NULL); +} + +static void stream_lock(struct stream_lock *lock) { + pthread_mutex_lock(&lock->pre_lock); + pthread_mutex_lock(&lock->lock); + pthread_mutex_unlock(&lock->pre_lock); +} + +static void stream_unlock(struct stream_lock *lock) { + pthread_mutex_unlock(&lock->lock); +} + +static void device_lock(struct audio_device *adev) { + pthread_mutex_lock(&adev->lock); +} + +static int device_try_lock(struct audio_device *adev) { + return pthread_mutex_trylock(&adev->lock); +} + +static void device_unlock(struct audio_device *adev) { + pthread_mutex_unlock(&adev->lock); +} + +/* + * streams list management + */ static void adev_add_stream_to_list( struct audio_device* adev, struct listnode* list, struct listnode* stream_node) { - pthread_mutex_lock(&adev->lock); + device_lock(adev); list_add_tail(list, stream_node); - pthread_mutex_unlock(&adev->lock); + device_unlock(adev); } static void adev_remove_stream_from_list( struct audio_device* adev, struct listnode* stream_node) { - pthread_mutex_lock(&adev->lock); + device_lock(adev); list_remove(stream_node); - pthread_mutex_unlock(&adev->lock); + device_unlock(adev); } /* - * NOTE: when multiple mutexes have to be acquired, always take the - * stream_in or stream_out mutex first, followed by the audio_device mutex. - * stream pre_lock is always acquired before stream lock to prevent starvation of control thread by - * higher priority playback or capture thread. - */ - -/* * Extract the card and device numbers from the supplied key/value pairs. * kvpairs A null-terminated string containing the key/value pairs or card and device. * i.e. "card=1;device=42" @@ -239,20 +277,6 @@ static char * device_get_parameters(alsa_device_profile * profile, const char * return result_str; } -void lock_input_stream(struct stream_in *in) -{ - pthread_mutex_lock(&in->pre_lock); - pthread_mutex_lock(&in->lock); - pthread_mutex_unlock(&in->pre_lock); -} - -void lock_output_stream(struct stream_out *out) -{ - pthread_mutex_lock(&out->pre_lock); - pthread_mutex_lock(&out->lock); - pthread_mutex_unlock(&out->pre_lock); -} - /* * HAl Functions */ @@ -310,15 +334,14 @@ static int out_standby(struct audio_stream *stream) { struct stream_out *out = (struct stream_out *)stream; - lock_output_stream(out); + stream_lock(&out->lock); if (!out->standby) { - pthread_mutex_lock(&out->adev->lock); + device_lock(out->adev); proxy_close(&out->proxy); - pthread_mutex_unlock(&out->adev->lock); + device_unlock(out->adev); out->standby = true; } - pthread_mutex_unlock(&out->lock); - + stream_unlock(&out->lock); return 0; } @@ -352,9 +375,9 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) return ret_value; } - lock_output_stream(out); + stream_lock(&out->lock); /* Lock the device because that is where the profile lives */ - pthread_mutex_lock(&out->adev->lock); + device_lock(out->adev); if (!profile_is_cached_for(out->profile, card, device)) { /* cannot read pcm device info if playback is active */ @@ -373,8 +396,8 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) } } - pthread_mutex_unlock(&out->adev->lock); - pthread_mutex_unlock(&out->lock); + device_unlock(out->adev); + stream_unlock(&out->lock); return ret_value; } @@ -382,14 +405,13 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) static char * out_get_parameters(const struct audio_stream *stream, const char *keys) { struct stream_out *out = (struct stream_out *)stream; - lock_output_stream(out); - pthread_mutex_lock(&out->adev->lock); + stream_lock(&out->lock); + device_lock(out->adev); char * params_str = device_get_parameters(out->profile, keys); - pthread_mutex_unlock(&out->lock); - pthread_mutex_unlock(&out->adev->lock); - + device_unlock(out->adev); + stream_unlock(&out->lock); return params_str; } @@ -417,11 +439,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si int ret; struct stream_out *out = (struct stream_out *)stream; - lock_output_stream(out); + stream_lock(&out->lock); if (out->standby) { - pthread_mutex_lock(&out->adev->lock); + device_lock(out->adev); ret = start_output_stream(out); - pthread_mutex_unlock(&out->adev->lock); + device_unlock(out->adev); if (ret != 0) { goto err; } @@ -456,12 +478,12 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, si proxy_write(&out->proxy, write_buff, num_write_buff_bytes); } - pthread_mutex_unlock(&out->lock); + stream_unlock(&out->lock); return bytes; err: - pthread_mutex_unlock(&out->lock); + stream_unlock(&out->lock); if (ret != 0) { usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) / out_get_sample_rate(&stream->common)); @@ -479,12 +501,12 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, uint64_t *frames, struct timespec *timestamp) { struct stream_out *out = (struct stream_out *)stream; // discard const qualifier - lock_output_stream(out); + stream_lock(&out->lock); const alsa_device_proxy *proxy = &out->proxy; const int ret = proxy_get_presentation_position(proxy, frames, timestamp); - pthread_mutex_unlock(&out->lock); + stream_unlock(&out->lock); return ret; } @@ -541,11 +563,10 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, out->stream.get_presentation_position = out_get_presentation_position; out->stream.get_next_write_timestamp = out_get_next_write_timestamp; - pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL); - pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL); + stream_lock_init(&out->lock); out->adev = (struct audio_device *)hw_dev; - pthread_mutex_lock(&out->adev->lock); + device_lock(out->adev); out->profile = &out->adev->out_profile; // build this to hand to the alsa_device_proxy @@ -570,7 +591,7 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, } out->adev->device_sample_rate = config->sample_rate; - pthread_mutex_unlock(&out->adev->lock); + device_unlock(out->adev); /* Format */ if (config->format == AUDIO_FORMAT_DEFAULT) { @@ -654,9 +675,9 @@ static void adev_close_output_stream(struct audio_hw_device *hw_dev, out->conversion_buffer = NULL; out->conversion_buffer_size = 0; - pthread_mutex_lock(&out->adev->lock); + device_lock(out->adev); out->adev->device_sample_rate = 0; - pthread_mutex_unlock(&out->adev->lock); + device_unlock(out->adev); free(stream); } @@ -714,15 +735,15 @@ static int in_standby(struct audio_stream *stream) { struct stream_in *in = (struct stream_in *)stream; - lock_input_stream(in); + stream_lock(&in->lock); if (!in->standby) { - pthread_mutex_lock(&in->adev->lock); + device_lock(in->adev); proxy_close(&in->proxy); - pthread_mutex_unlock(&in->adev->lock); + device_unlock(in->adev); in->standby = true; } - pthread_mutex_unlock(&in->lock); + stream_unlock(&in->lock); return 0; } @@ -759,8 +780,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) return ret_value; } - lock_input_stream(in); - pthread_mutex_lock(&in->adev->lock); + stream_lock(&in->lock); + device_lock(in->adev); if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) { /* cannot read pcm device info if playback is active */ @@ -779,8 +800,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) } } - pthread_mutex_unlock(&in->adev->lock); - pthread_mutex_unlock(&in->lock); + device_unlock(in->adev); + stream_unlock(&in->lock); return ret_value; } @@ -789,13 +810,13 @@ static char * in_get_parameters(const struct audio_stream *stream, const char *k { struct stream_in *in = (struct stream_in *)stream; - lock_input_stream(in); - pthread_mutex_lock(&in->adev->lock); + stream_lock(&in->lock); + device_lock(in->adev); char * params_str = device_get_parameters(in->profile, keys); - pthread_mutex_unlock(&in->adev->lock); - pthread_mutex_unlock(&in->lock); + device_unlock(in->adev); + stream_unlock(&in->lock); return params_str; } @@ -833,11 +854,11 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte struct stream_in * in = (struct stream_in *)stream; - lock_input_stream(in); + stream_lock(&in->lock); if (in->standby) { - pthread_mutex_lock(&in->adev->lock); + device_lock(in->adev); ret = start_input_stream(in); - pthread_mutex_unlock(&in->adev->lock); + device_unlock(in->adev); if (ret != 0) { goto err; } @@ -895,8 +916,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte } err: - pthread_mutex_unlock(&in->lock); - + stream_unlock(&in->lock); return num_read_buff_bytes; } @@ -942,11 +962,10 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, in->stream.read = in_read; in->stream.get_input_frames_lost = in_get_input_frames_lost; - pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); - pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); + stream_lock_init(&in->lock); in->adev = (struct audio_device *)hw_dev; - pthread_mutex_lock(&in->adev->lock); + device_lock(in->adev); in->profile = &in->adev->in_profile; @@ -973,7 +992,7 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile); ret = -EINVAL; } - pthread_mutex_unlock(&in->adev->lock); + device_unlock(in->adev); /* Format */ if (config->format == AUDIO_FORMAT_DEFAULT) { @@ -1077,9 +1096,9 @@ static int adev_set_mode(struct audio_hw_device *hw_dev, audio_mode_t mode) static int adev_set_mic_mute(struct audio_hw_device *hw_dev, bool state) { struct audio_device * adev = (struct audio_device *)hw_dev; - pthread_mutex_lock(&adev->lock); + device_lock(adev); adev->mic_muted = state; - pthread_mutex_unlock(&adev->lock); + device_unlock(adev); return -ENOSYS; } @@ -1096,9 +1115,9 @@ static int adev_dump(const struct audio_hw_device *device, int fd) const int kNumRetries = 3; const int kSleepTimeMS = 500; - // use pthread_mutex_trylock() in case we dumpsys during a deadlock + // use device_try_lock() in case we dumpsys during a deadlock int retry = kNumRetries; - while (retry > 0 && pthread_mutex_trylock(&adev->lock) != 0) { + while (retry > 0 && device_try_lock(adev) != 0) { sleep(kSleepTimeMS); retry--; } @@ -1126,7 +1145,7 @@ static int adev_dump(const struct audio_hw_device *device, int fd) } } - pthread_mutex_unlock(&adev->lock); + device_unlock(adev); } else { // Couldn't lock dprintf(fd, " Could not obtain device lock.\n"); |