[alsa-devel] [PATCH] Provide card number / PID via sequencer client info
Takashi Iwai
tiwai at suse.de
Mon Feb 15 20:08:12 CET 2016
On Mon, 15 Feb 2016 19:32:43 +0100,
Martin Koegler wrote:
>
> On Mon, Feb 15, 2016 at 11:30:15AM +0100, Takashi Iwai wrote:
> > The idea looks good. One remaining question is whether only providing
> > the card number or pid is sufficient for all cases.
>
> I only care about the kernel client.
Well, the question is whether only card number is enough. What if
cards provide multiple rawmidi devices?
> > > @@ -357,7 +357,8 @@ struct snd_seq_client_info {
> > > unsigned char event_filter[32]; /* event filter bitmap */
> > > int num_ports; /* RO: number of ports */
> > > int event_lost; /* number of lost events */
> > > - char reserved[64]; /* for future use */
> > > + int owner; /* RO: card number[kernel] / PID[user] */
> > > + char reserved[64 - sizeof(int)]; /* for future use */
> >
> > The sizeof(int) is always 4. So let's make it explicit.
> >
> > But, please make sure that this change won't lead to any
> > incompatibility. Some architectures might align with 64bit long,
> > although the 32bit int and the rest char[] should be fine on all known
> > architectures, AFAIK.
>
> Sorry, I don't have access to the various non x86-architectures, so I can't test.
Usually it's tested by cross-compiling, so everyone can do it.
>
> I will change to
> int card;
> int pid;
> char reserve[56];
Yes, this would be better.
> More safety would just provide a much more complex (ugly?) structure:
>
> struct _int_snd_seq_client_info_old {
> int client; /* client number to inquire */
> snd_seq_client_type_t type; /* client type */
> char name[64]; /* client name */
> unsigned int filter; /* filter flags */
> unsigned char multicast_filter[8]; /* multicast filter bitmap */
> unsigned char event_filter[32]; /* event filter bitmap */
> int num_ports; /* RO: number of ports */
> int event_lost; /* number of lost events */
> char reserved[64]; /* for future use */
> };
>
> struct _int_snd_seq_client_info_new {
> int client; /* client number to inquire */
> snd_seq_client_type_t type; /* client type */
> char name[64]; /* client name */
> unsigned int filter; /* filter flags */
> unsigned char multicast_filter[8]; /* multicast filter bitmap */
> unsigned char event_filter[32]; /* event filter bitmap */
> int num_ports; /* RO: number of ports */
> int event_lost; /* number of lost events */
> int card;
> int pid;
> char reserved[64]; /* for future use */
> };
>
> struct snd_seq_client_info {
> int client; /* client number to inquire */
> snd_seq_client_type_t type; /* client type */
> char name[64]; /* client name */
> unsigned int filter; /* filter flags */
> unsigned char multicast_filter[8]; /* multicast filter bitmap */
> unsigned char event_filter[32]; /* event filter bitmap */
> int num_ports; /* RO: number of ports */
> int event_lost; /* number of lost events */
> int card;
> int pid;
> char reserved[64 - sizeof(struct _int_snd_seq_client_info_new) + sizeof(_int_snd_seq_client_info_old)]; /* for future use */
> };
>
> This should handle all alignment and type size issues automatically.
You'd need to define old and new structs without reserved field.
The calculation still works but it's bogus.
> If you really want this, I can provide the apropriate patches.
No, I never want such a thing :)
> > >
> > > diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
> > > index 58e79e0..ac07ab7 100644
> > > --- a/sound/core/seq/seq_clientmgr.c
> > > +++ b/sound/core/seq/seq_clientmgr.c
> > > @@ -364,6 +364,7 @@ static int snd_seq_open(struct inode *inode, struct file *file)
> > > /* fill client data */
> > > user->file = file;
> > > sprintf(client->name, "Client-%d", c);
> > > + client->data.user.owner = get_pid(task_pid(current));
> > >
> > > /* make others aware this new client */
> > > snd_seq_system_client_ev_client_start(c);
> > > @@ -380,6 +381,7 @@ static int snd_seq_release(struct inode *inode, struct file *file)
> > > seq_free_client(client);
> > > if (client->data.user.fifo)
> > > snd_seq_fifo_delete(&client->data.user.fifo);
> > > + put_pid(client->data.user.owner);
> > > kfree(client);
> > > }
> >
> > Shouldn't the counterpart (put_pid()) be called anywhere else?
>
> The only way to free a client structure is seq_free_client1 (static).
> This is called by snd_seq_open before get_pid [=> irelevant] and
> seq_free_client (static).
> seq_free_client is called by snd_seq_release, which calls put_pid and
> snd_seq_delete_kernel_client, which destroys a kernel client.
OK, I misread the patch where to place the code. Then this should be
fine.
Takashi
More information about the Alsa-devel
mailing list