From: Takashi Iwai <tiwai@suse.de>
To: Marcel Holtmann <marcel@holtmann.org>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: External PCM plugin SDK
Date: Fri, 11 Feb 2005 18:26:17 +0100 [thread overview]
Message-ID: <s5h1xbnhuti.wl@alsa2.suse.de> (raw)
In-Reply-To: <s5hbrarz0n1.wl@alsa2.suse.de>
[-- Attachment #1: Type: text/plain, Size: 1729 bytes --]
At Fri, 11 Feb 2005 14:28:34 +0100,
I wrote:
>
> At Fri, 11 Feb 2005 13:15:19 +0100,
> Marcel Holtmann wrote:
> >
> > Hi Takashi,
> >
> > > > > ... and doesn't work as it is, unfortunately :-<
> > > > >
> > > > > dlcose() is called after snd_pcm_close().
> > > > > We may need to build object caches in alsa-lib.
> > > > > This will improve the perfomance eventually, too.
> > > >
> > > > questions is what will break if you change it. The only official plugin
> > > > is the Jack plugin, right? So be bad and change this stuff and then fix
> > > > the plugins.
> > >
> > > The compatibility will be kept, I think. Only the plugins with a
> > > keep-alive flag are excluded from dlclose, and the objects are reused
> > > at the next open.
> >
> > but I think we still should implement something like init() and exit()
> > of the objects. Otherwise it would not be possible to handle this in a
> > correct way and we will get memory leaks and unclosed descriptors.
>
> We can add the clean up of cached plugin objects (i.e. calling
> dlclose) in the existing snd_config_update_free_global(). This
> function is supposed to be used for clean up of config tree cache.
>
> Each plugin with the keep-alive flag can have functions with
> __attribute__((constructor)) and __attribute__((destructor)) for the
> purpose above.
The below is a test patch to add the dlobj cache.
It adds a new mode flag to pcm open mode, SND_PCM_KEEP_ALIVE.
In xmms, change the call of snd_pcm_open() like:
snd_pcm_open(...., SND_PCM_NONBLOCK | SND_PCM_KEEP_ALIVE);
and the dl object will remain alive until
snd_config_update_free_global() is called explicitly.
If the plugin needs always keep-alive, a bit more change is needed.
Takashi
[-- Attachment #2: Type: text/plain, Size: 5552 bytes --]
Index: alsa-lib/include/local.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/include/local.h,v
retrieving revision 1.37
diff -u -r1.37 local.h
--- alsa-lib/include/local.h 11 Feb 2005 16:20:31 -0000 1.37
+++ alsa-lib/include/local.h 11 Feb 2005 16:58:50 -0000
@@ -232,4 +232,9 @@
#define snd_open_device(filename, fmode) open(filename, fmode);
#endif
+/* dlobj cache */
+void *snd_dlobj_cache_lookup(const char *name);
+int snd_dlobj_cache_add(const char *name, void *dlobj, void *open_func);
+void snd_dlobj_cache_cleanup(void);
+
#endif
Index: alsa-lib/include/pcm.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/include/pcm.h,v
retrieving revision 1.102
diff -u -r1.102 pcm.h
--- alsa-lib/include/pcm.h 7 Feb 2005 20:53:06 -0000 1.102
+++ alsa-lib/include/pcm.h 11 Feb 2005 17:12:50 -0000
@@ -295,6 +295,8 @@
#define SND_PCM_NONBLOCK 0x0001
/** Async notification (flag for open mode) \hideinitializer */
#define SND_PCM_ASYNC 0x0002
+/** Keep the dl object alive after close */
+#define SND_PCM_KEEP_ALIVE 0x0004
/** PCM handle */
typedef struct _snd_pcm snd_pcm_t;
Index: alsa-lib/include/pcm_ioplug.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/include/pcm_ioplug.h,v
retrieving revision 1.3
diff -u -r1.3 pcm_ioplug.h
--- alsa-lib/include/pcm_ioplug.h 8 Feb 2005 20:48:56 -0000 1.3
+++ alsa-lib/include/pcm_ioplug.h 11 Feb 2005 17:14:59 -0000
@@ -37,10 +37,13 @@
typedef struct snd_pcm_ioplug snd_pcm_ioplug_t;
typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
+#define SND_PCM_IOPLUG_FLAG_LISTED (1<<0)
+
/* exported pcm data */
struct snd_pcm_ioplug {
/* must be filled before calling snd_pcm_ioplug_create() */
const char *name;
+ unsigned int flags; /* SND_PCM_IOPLUG_FLAG_XXX */
int poll_fd;
unsigned int poll_events;
unsigned int mmap_rw; /* pseudo mmap */
Index: alsa-lib/src/conf.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/src/conf.c,v
retrieving revision 1.58
diff -u -r1.58 conf.c
--- alsa-lib/src/conf.c 9 Feb 2005 16:57:45 -0000 1.58
+++ alsa-lib/src/conf.c 11 Feb 2005 17:00:06 -0000
@@ -3105,6 +3105,10 @@
snd_config_update_free(snd_config_global_update);
snd_config_global_update = NULL;
pthread_mutex_unlock(&snd_config_update_mutex);
+
+ /* FIXME: better to place this in another place... */
+ snd_dlobj_cache_cleanup();
+
return 0;
}
Index: alsa-lib/src/dlmisc.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/src/dlmisc.c,v
retrieving revision 1.8
diff -u -r1.8 dlmisc.c
--- alsa-lib/src/dlmisc.c 9 Dec 2002 10:58:48 -0000 1.8
+++ alsa-lib/src/dlmisc.c 11 Feb 2005 17:19:10 -0000
@@ -29,6 +29,7 @@
#define _GNU_SOURCE
#include <dlfcn.h>
+#include "list.h"
#include "local.h"
#ifndef DOC_HIDDEN
@@ -143,3 +144,70 @@
return NULL;
return dlsym(handle, name);
}
+
+/*
+ * dlobj cache
+ *
+ * FIXME: add reference counter and proper locking
+ */
+
+struct dlobj_cache {
+ const char *name;
+ void *obj;
+ void *func;
+ struct list_head list;
+};
+
+static LIST_HEAD(pcm_dlobj_list);
+
+void *snd_dlobj_cache_lookup(const char *name)
+{
+ struct list_head *p;
+ struct dlobj_cache *c;
+
+ list_for_each(p, &pcm_dlobj_list) {
+ c = list_entry(p, struct dlobj_cache, list);
+ if (strcmp(c->name, name) == 0)
+ return c->func;
+ }
+ return NULL;
+}
+
+int snd_dlobj_cache_add(const char *name, void *dlobj, void *open_func)
+{
+ struct list_head *p;
+ struct dlobj_cache *c;
+
+ list_for_each(p, &pcm_dlobj_list) {
+ c = list_entry(p, struct dlobj_cache, list);
+ if (strcmp(c->name, name) == 0)
+ return 0; /* already exists */
+ }
+ c = malloc(sizeof(*c));
+ if (! c)
+ return -ENOMEM;
+ c->name = strdup(name);
+ if (! c->name) {
+ free(c);
+ return -ENOMEM;
+ }
+ c->obj = dlobj;
+ c->func = open_func;
+ list_add_tail(&c->list, &pcm_dlobj_list);
+ return 0;
+}
+
+void snd_dlobj_cache_cleanup(void)
+{
+ struct list_head *p;
+ struct dlobj_cache *c;
+
+ while (! list_empty(&pcm_dlobj_list)) {
+ p = pcm_dlobj_list.next;
+ c = list_entry(p, struct dlobj_cache, list);
+ list_del(p);
+ snd_dlclose(c->obj);
+ free(c->name);
+ free(c);
+ }
+}
Index: alsa-lib/src/pcm/pcm.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-lib/src/pcm/pcm.c,v
retrieving revision 1.168
diff -u -r1.168 pcm.c
--- alsa-lib/src/pcm/pcm.c 21 Jan 2005 19:27:44 -0000 1.168
+++ alsa-lib/src/pcm/pcm.c 11 Feb 2005 17:20:36 -0000
@@ -2019,6 +2019,11 @@
#ifndef PIC
snd_pcm_open_symbols(); /* this call is for static linking only */
#endif
+ open_func = snd_dlobj_cache_lookup(open_name);
+ if (open_func) {
+ err = 0;
+ goto _err;
+ }
h = snd_dlopen(lib, RTLD_NOW);
if (h)
open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION));
@@ -2032,17 +2037,22 @@
err = -ENXIO;
}
_err:
- if (type_conf)
- snd_config_delete(type_conf);
if (err >= 0) {
err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
if (err >= 0) {
+ if (h && (mode & SND_PCM_KEEP_ALIVE)) {
+ snd_dlobj_cache_add(open_name, h, open_func);
+ h = NULL;
+ }
(*pcmp)->dl_handle = h;
err = 0;
} else {
- snd_dlclose(h);
+ if (h)
+ snd_dlclose(h);
}
}
+ if (type_conf)
+ snd_config_delete(type_conf);
if (buf)
free(buf);
if (buf1)
next prev parent reply other threads:[~2005-02-11 17:26 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-02-08 21:30 External PCM plugin SDK Takashi Iwai
2005-02-09 14:14 ` Marcel Holtmann
2005-02-09 14:20 ` Takashi Iwai
2005-02-09 14:37 ` Marcel Holtmann
2005-02-09 15:19 ` Takashi Iwai
2005-02-09 17:27 ` Marcel Holtmann
2005-02-09 17:32 ` Takashi Iwai
2005-02-09 17:48 ` Marcel Holtmann
2005-02-10 11:51 ` Takashi Iwai
2005-02-10 12:29 ` Marcel Holtmann
2005-02-10 17:29 ` Takashi Iwai
[not found] ` <1108057507.15974.97.camel@pegasus>
2005-02-10 17:51 ` Takashi Iwai
2005-02-10 18:06 ` Marcel Holtmann
2005-02-10 18:21 ` Takashi Iwai
2005-02-10 18:30 ` Takashi Iwai
2005-02-10 19:04 ` Marcel Holtmann
2005-02-11 10:50 ` Takashi Iwai
2005-02-11 12:15 ` Marcel Holtmann
2005-02-11 13:28 ` Takashi Iwai
2005-02-11 17:26 ` Takashi Iwai [this message]
2005-02-12 2:18 ` Marcel Holtmann
2005-02-14 15:33 ` Takashi Iwai
2005-02-09 17:38 ` Thierry Vignaud
2005-02-09 17:35 ` Takashi Iwai
2005-02-09 15:25 ` Jaroslav Kysela
2005-02-09 15:39 ` Takashi Iwai
2005-02-09 17:36 ` Thierry Vignaud
2005-02-09 17:38 ` Marcel Holtmann
2005-02-09 15:28 ` Alexander E. Patrakov
2005-02-09 15:29 ` Takashi Iwai
2005-02-09 17:40 ` Thierry Vignaud
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5h1xbnhuti.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@lists.sourceforge.net \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.