Hi,
trying lash-0.5.3 here, weired things happened:
I set up a simple project with only 1 lash_synth, the lash_synth
was connected to an alsa-sequencer keyboard port and to jack.
After saving, closing and restarting that lash-project,
the alsa-sequencer connection wasn't restored, until I launched an
innocent "aconnect -il" in an other terminal.
Funny, no?
Reason is I think, that after polling for alsa-seq events, always
only 1 event was red via snd_seq_event_input().
Attached patch cures & simplifies things by avoiding the poll() call
and using pthread_cancel() to stop the thread.
Karsten
--- lashd/alsa_mgr-0.5.3.h 2006-06-09 04:54:00.000000000 +0200
+++ lashd/alsa_mgr.h 2007-08-21 20:28:50.000000000 +0200
@@ -44,8 +44,6 @@ struct _alsa_mgr
lash_list_t * clients;
lash_list_t * foreign_ports;
-
- int quit;
};
--- lashd/alsa_mgr-0.5.3.c 2005-09-15 10:23:29.000000000 +0200
+++ lashd/alsa_mgr.c 2007-08-21 20:39:59.000000000 +0200
@@ -36,7 +36,7 @@
#define BACKUP_TIMEOUT ((time_t)(30))
-void *alsa_mgr_event_run(void *data);
+static void *alsa_mgr_event_run(void *data);
static void alsa_mgr_new_client_port(alsa_mgr_t * alsa_mgr, uuid_t client_id,
unsigned char port);
@@ -114,9 +114,13 @@ alsa_mgr_destroy(alsa_mgr_t * alsa_mgr)
{
int err;
- alsa_mgr->quit = 1;
-
LASH_PRINT_DEBUG("stopping");
+
+ err = pthread_cancel(alsa_mgr->event_thread);
+ if (err)
+ fprintf(stderr, "%s: error canceling event thread: %s\n", __FUNCTION__,
+ snd_strerror(err));
+
err = pthread_join(alsa_mgr->event_thread, NULL);
if (err) {
fprintf(stderr, "%s: error joining event thread: %s\n", __FUNCTION__,
@@ -539,31 +543,7 @@ alsa_mgr_redo_patches(alsa_mgr_t * alsa_
LASH_PRINT_DEBUG("end");
}
-void
-alsa_mgr_recieve_event(alsa_mgr_t * alsa_mgr)
-{
- snd_seq_event_t *ev;
- int err;
-
- err = snd_seq_event_input(alsa_mgr->seq, &ev);
-
- switch (ev->type) {
- case SND_SEQ_EVENT_PORT_START:
- LASH_PRINT_DEBUG("new port");
- alsa_mgr_new_port(alsa_mgr, ev->data.addr.client, ev->data.addr.port);
- break;
- case SND_SEQ_EVENT_PORT_EXIT:
- alsa_mgr_port_removed(alsa_mgr, ev->data.addr.client,
- ev->data.addr.port);
- break;
- case SND_SEQ_EVENT_PORT_SUBSCRIBED:
- case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
- alsa_mgr_redo_patches(alsa_mgr);
- break;
- }
-}
-
-void
+static void
alsa_mgr_backup_patches(alsa_mgr_t * alsa_mgr)
{
static time_t last_backup = 0;
@@ -590,59 +570,52 @@ alsa_mgr_backup_patches(alsa_mgr_t * als
last_backup = now;
}
-void *
-alsa_mgr_event_run(void *data)
+static void
+alsa_mgr_recieve_event(alsa_mgr_t * alsa_mgr)
{
- alsa_mgr_t *alsa_mgr;
- int err;
- struct pollfd *pfds;
- int nfds, i;
- unsigned short *revents;
-
- alsa_mgr = (alsa_mgr_t *) data;
-
- nfds = snd_seq_poll_descriptors_count(alsa_mgr->seq, POLLIN);
- pfds = lash_malloc(sizeof(struct pollfd) * nfds);
- revents = lash_malloc(sizeof(unsigned short) * nfds);
- snd_seq_poll_descriptors(alsa_mgr->seq, pfds, nfds, POLLIN);
-
- while (!alsa_mgr->quit) {
- err = poll(pfds, nfds, 1000);
- if (err == -1) {
- if (errno == EINTR)
- continue;
-
- fprintf(stderr, "%s: error polling alsa sequencer: %s\n",
- __FUNCTION__, strerror(errno));
- continue;
- }
-
- if (alsa_mgr->quit)
- break;
+ snd_seq_event_t *ev;
+ int err, backup;
- alsa_mgr_lock(alsa_mgr);
- err =
- snd_seq_poll_descriptors_revents(alsa_mgr->seq, pfds, nfds,
- revents);
- if (err) {
- fprintf(stderr,
- "%s: error getting alsa sequencer poll revents: %s\n",
- __FUNCTION__, snd_strerror(err));
- continue;
- }
+ err = snd_seq_event_input(alsa_mgr->seq, &ev);
+ if (err < 0)
+ return;
- for (i = 0; i < nfds; i++) {
- if (revents[i] > 0)
- alsa_mgr_recieve_event(alsa_mgr);
- }
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ alsa_mgr_lock(alsa_mgr);
+ backup = 1;
+ switch (ev->type) {
+ case SND_SEQ_EVENT_PORT_START:
+ LASH_PRINT_DEBUG("new port");
+ alsa_mgr_new_port(alsa_mgr, ev->data.addr.client, ev->data.addr.port);
+ break;
+ case SND_SEQ_EVENT_PORT_EXIT:
+ alsa_mgr_port_removed(alsa_mgr, ev->data.addr.client,
+ ev->data.addr.port);
+ break;
+ case SND_SEQ_EVENT_PORT_SUBSCRIBED:
+ case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
+ alsa_mgr_redo_patches(alsa_mgr);
+ break;
+ default:
+ backup = 0;
+ LASH_DEBUGARGS("unhandled ev->type=%u", ev->type);
+ break;
+ }
+ if (backup)
alsa_mgr_backup_patches(alsa_mgr);
- alsa_mgr_unlock(alsa_mgr);
- }
+ alsa_mgr_unlock(alsa_mgr);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+}
+
+static void *
+alsa_mgr_event_run(void *data)
+{
+ alsa_mgr_t *alsa_mgr = (alsa_mgr_t *)data;
- free(revents);
- free(pfds);
+ while (1)
+ alsa_mgr_recieve_event(alsa_mgr);
LASH_PRINT_DEBUG("finished");
return NULL;
_______________________________________________
Linux-audio-dev mailing list
[email protected]
http://lists.linuxaudio.org/mailman/listinfo.cgi/linux-audio-dev