提交 89b4ab21 编写于 作者: T Takashi Iwai

ALSA: seq: virmidi: Use READ_ONCE/WRITE_ONCE() macros

The trigger flag in vmidi object can be referred in different contexts
concurrently, hence it's better to be put with READ_ONCE() and
WRITE_ONCE() macros to assure the accesses.
Signed-off-by: NTakashi Iwai <tiwai@suse.de>
上级 f7debfe5
...@@ -36,7 +36,7 @@ struct snd_virmidi { ...@@ -36,7 +36,7 @@ struct snd_virmidi {
int seq_mode; int seq_mode;
int client; int client;
int port; int port;
unsigned int trigger: 1; bool trigger;
struct snd_midi_event *parser; struct snd_midi_event *parser;
struct snd_seq_event event; struct snd_seq_event event;
struct snd_virmidi_dev *rdev; struct snd_virmidi_dev *rdev;
......
...@@ -89,7 +89,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev, ...@@ -89,7 +89,7 @@ static int snd_virmidi_dev_receive_event(struct snd_virmidi_dev *rdev,
else else
down_read(&rdev->filelist_sem); down_read(&rdev->filelist_sem);
list_for_each_entry(vmidi, &rdev->filelist, list) { list_for_each_entry(vmidi, &rdev->filelist, list) {
if (!vmidi->trigger) if (!READ_ONCE(vmidi->trigger))
continue; continue;
if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE) if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
...@@ -147,11 +147,7 @@ static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, i ...@@ -147,11 +147,7 @@ static void snd_virmidi_input_trigger(struct snd_rawmidi_substream *substream, i
{ {
struct snd_virmidi *vmidi = substream->runtime->private_data; struct snd_virmidi *vmidi = substream->runtime->private_data;
if (up) { WRITE_ONCE(vmidi->trigger, !!up);
vmidi->trigger = 1;
} else {
vmidi->trigger = 0;
}
} }
/* process rawmidi bytes and send events; /* process rawmidi bytes and send events;
...@@ -175,7 +171,7 @@ static void snd_vmidi_output_work(struct work_struct *work) ...@@ -175,7 +171,7 @@ static void snd_vmidi_output_work(struct work_struct *work)
return; return;
} }
while (vmidi->trigger) { while (READ_ONCE(vmidi->trigger)) {
if (snd_rawmidi_transmit(substream, &input, 1) != 1) if (snd_rawmidi_transmit(substream, &input, 1) != 1)
break; break;
if (snd_midi_event_encode_byte(vmidi->parser, input, if (snd_midi_event_encode_byte(vmidi->parser, input,
...@@ -201,7 +197,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, ...@@ -201,7 +197,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
{ {
struct snd_virmidi *vmidi = substream->runtime->private_data; struct snd_virmidi *vmidi = substream->runtime->private_data;
vmidi->trigger = !!up; WRITE_ONCE(vmidi->trigger, !!up);
if (up) if (up)
queue_work(system_highpri_wq, &vmidi->output_work); queue_work(system_highpri_wq, &vmidi->output_work);
} }
...@@ -289,7 +285,7 @@ static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream) ...@@ -289,7 +285,7 @@ static int snd_virmidi_output_close(struct snd_rawmidi_substream *substream)
{ {
struct snd_virmidi *vmidi = substream->runtime->private_data; struct snd_virmidi *vmidi = substream->runtime->private_data;
vmidi->trigger = 0; /* to be sure */ WRITE_ONCE(vmidi->trigger, false); /* to be sure */
cancel_work_sync(&vmidi->output_work); cancel_work_sync(&vmidi->output_work);
snd_midi_event_free(vmidi->parser); snd_midi_event_free(vmidi->parser);
substream->runtime->private_data = NULL; substream->runtime->private_data = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册